The Samba-Bugzilla – Attachment 15733 Details for
Bug 14236
[FUZZING] Unsigned integer overflow in ndr_pull_advance
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch for V4-11
bug-1414263-v4-11-01.patch (text/plain), 1.23 MB, created by
Gary Lockyer
on 2020-01-15 20:15:47 UTC
(
hide
)
Description:
Proposed patch for V4-11
Filename:
MIME Type:
Creator:
Gary Lockyer
Created:
2020-01-15 20:15:47 UTC
Size:
1.23 MB
patch
obsolete
>From ac9740a0966c42ce08e92737fa0b8e476cdd490b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 9 Jul 2019 12:03:38 +0200 >Subject: [PATCH 001/376] VERSION: Bump version up to 4.11.0rc2... > >and re-enable GIT_SNAPSHOT. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index e9931834e6c..c70b521219c 100644 >--- a/VERSION >+++ b/VERSION >@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= > # e.g. SAMBA_VERSION_RC_RELEASE=1 # > # -> "3.0.0rc1" # > ######################################################## >-SAMBA_VERSION_RC_RELEASE=1 >+SAMBA_VERSION_RC_RELEASE=2 > > ######################################################## > # To mark SVN snapshots this should be set to 'yes' # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=1 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=no >+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From 1c64a2e37b695fcae9f64dea6f82c6fcadc990c4 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 9 Jul 2019 12:21:10 +0200 >Subject: [PATCH 002/376] WHATSNEW: preview release -> release candidate > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index c0d13d20d6b..b07e9eba778 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -1,7 +1,7 @@ > Release Announcements > ===================== > >-This is the first preview release of Samba 4.11. This is *not* >+This is the second release candidate of Samba 4.11. This is *not* > intended for production environments and is designed for testing > purposes only. Please report any defects via the Samba bug reporting > system at https://bugzilla.samba.org/. >-- >2.17.1 > > >From 6877eabea8f34e49b2ccec3ac1793600b8a0475e Mon Sep 17 00:00:00 2001 >From: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Date: Thu, 11 Jul 2019 17:12:06 +1200 >Subject: [PATCH 003/376] partition: correcting lock ordering > >A schema reading bug was traced to a lock ordering issue in partition.c. >This patch fixes the problem by: >1. Releasing locks/transactions in the order they were acquired. >2. Always lock/start_trans on metadata.tdb first, before any other >databases, and release it last, after all others. This is so that we are >never exposed to MDB's lock semantics, which we don't support. > >Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7f4bc0ea81f2b34607849911f1271b030be8ca02) >--- > source4/dsdb/samdb/ldb_modules/partition.c | 135 +++++++++++++-------- > 1 file changed, 84 insertions(+), 51 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c >index 4cfcf6f3ba7..93fa129c14e 100644 >--- a/source4/dsdb/samdb/ldb_modules/partition.c >+++ b/source4/dsdb/samdb/ldb_modules/partition.c >@@ -1032,8 +1032,8 @@ static int partition_rename(struct ldb_module *module, struct ldb_request *req) > /* start a transaction */ > int partition_start_trans(struct ldb_module *module) > { >- int i; >- int ret; >+ int i = 0; >+ int ret = 0; > struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module), > struct partition_private_data); > /* Look at base DN */ >@@ -1043,18 +1043,58 @@ int partition_start_trans(struct ldb_module *module) > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_start_trans() -> (metadata partition)"); > } > >- /* This order must match that in prepare_commit() and read_lock() */ >+ /* >+ * We start a transaction on metadata.tdb first and end it last in >+ * end_trans. This makes locking semantics follow TDB rather than MDB, >+ * and effectively locks all partitions at once. >+ * Detail: >+ * Samba AD is special in that the partitions module (this file) >+ * combines multiple independently locked databases into one overall >+ * transaction. Changes across multiple partition DBs in a single >+ * transaction must ALL be either visible or invisible. >+ * The way this is achieved is by taking out a write lock on >+ * metadata.tdb at the start of prepare_commit, while unlocking it at >+ * the end of end_trans. This is matched by read_lock, ensuring it >+ * can't progress until that write lock is released. >+ * >+ * metadata.tdb needs to be a TDB file because MDB uses independent >+ * locks, which means a read lock and a write lock can be held at the >+ * same time, whereas in TDB, the two locks block each other. The TDB >+ * behaviour is required to implement the functionality described >+ * above. >+ * >+ * An important additional detail here is that if prepare_commit is >+ * called on a TDB without any changes being made, no write lock is >+ * taken. We address this by storing a sequence number in metadata.tdb >+ * which is updated every time a replicated attribute is modified. >+ * The possibility of a few unreplicated attributes being out of date >+ * turns out not to be a problem. >+ * For this reason, a lock on sam.ldb (which is a TDB) won't achieve >+ * the same end as locking metadata.tdb, unless we made a modification >+ * to the @ records found there before every prepare_commit. >+ */ >+ ret = partition_metadata_start_trans(module); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > ret = ldb_next_start_trans(module); > if (ret != LDB_SUCCESS) { >+ partition_metadata_del_trans(module); > return ret; > } > > ret = partition_reload_if_required(module, data, NULL); > if (ret != LDB_SUCCESS) { > ldb_next_del_trans(module); >+ partition_metadata_del_trans(module); > return ret; > } > >+ /* >+ * The following per partition locks are required mostly because TDB >+ * and MDB require locks before read and write ops are permitted. >+ */ > for (i=0; data && data->partitions && data->partitions[i]; i++) { > if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) { > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_start_trans() -> %s", >@@ -1072,20 +1112,6 @@ int partition_start_trans(struct ldb_module *module) > } > } > >- /* >- * Because in prepare_commit this must come last, to ensure >- * lock ordering we have to do this last here also >- */ >- ret = partition_metadata_start_trans(module); >- if (ret != LDB_SUCCESS) { >- /* Back it out, if it fails on one */ >- for (i--; i >= 0; i--) { >- ldb_next_del_trans(data->partitions[i]->module); >- } >- ldb_next_del_trans(module); >- return ret; >- } >- > data->in_transaction++; > > return LDB_SUCCESS; >@@ -1099,6 +1125,15 @@ int partition_prepare_commit(struct ldb_module *module) > struct partition_private_data); > int ret; > >+ /* >+ * Order of prepare_commit calls must match that in >+ * partition_start_trans. See comment in that function for detail. >+ */ >+ ret = partition_metadata_prepare_commit(module); >+ if (ret != LDB_SUCCESS) { >+ return ret; >+ } >+ > ret = ldb_next_prepare_commit(module); > if (ret != LDB_SUCCESS) { > return ret; >@@ -1122,9 +1157,7 @@ int partition_prepare_commit(struct ldb_module *module) > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> (metadata partition)"); > } > >- /* metadata prepare commit must come last, as other partitions could modify >- * the database inside the prepare commit method of a module */ >- return partition_metadata_prepare_commit(module); >+ return LDB_SUCCESS; > } > > >@@ -1145,7 +1178,10 @@ int partition_end_trans(struct ldb_module *module) > data->in_transaction--; > } > >- >+ /* >+ * Order of end_trans calls must be the reverse of that in >+ * partition_start_trans. See comment in that function for detail. >+ */ > for (i=0; data && data->partitions && data->partitions[i]; i++) { > if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) { > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> %s", >@@ -1184,6 +1220,10 @@ int partition_del_trans(struct ldb_module *module) > struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module), > struct partition_private_data); > >+ /* >+ * Order of del_trans calls must be the reverse of that in >+ * partition_start_trans. See comment in that function for detail. >+ */ > for (i=0; data && data->partitions && data->partitions[i]; i++) { > if (ldb_module_flags(ldb_module_get_ctx(module)) & > LDB_FLG_ENABLE_TRACING) { >@@ -1382,9 +1422,9 @@ static int partition_sequence_number(struct ldb_module *module, struct ldb_reque > /* lock all the backends */ > int partition_read_lock(struct ldb_module *module) > { >- int i; >- int ret; >- int ret2; >+ int i = 0; >+ int ret = 0; >+ int ret2 = 0; > struct ldb_context *ldb = ldb_module_get_ctx(module); > struct partition_private_data *data = \ > talloc_get_type(ldb_module_get_private(module), >@@ -1430,9 +1470,8 @@ int partition_read_lock(struct ldb_module *module) > } > > /* >- * This will lock the metadata partition (sam.ldb) and >- * will also call event loops, so we do it before we >- * get the whole db lock. >+ * This will lock sam.ldb and will also call event loops, >+ * so we do it before we get the whole db lock. > */ > ret = partition_reload_if_required(module, data, NULL); > if (ret != LDB_SUCCESS) { >@@ -1440,8 +1479,20 @@ int partition_read_lock(struct ldb_module *module) > } > > /* >- * This order must match that in prepare_commit(), start with >- * the top level DB (sam.ldb) lock >+ * Order of read_lock calls must match that in partition_start_trans. >+ * See comment in that function for detail. >+ */ >+ ret = partition_metadata_read_lock(module); >+ if (ret != LDB_SUCCESS) { >+ goto failed; >+ } >+ >+ /* >+ * The top level DB (sam.ldb) lock is not enough to block another >+ * process in prepare_commit(), because if nothing was changed in the >+ * specific backend, then prepare_commit() is a no-op. Therefore the >+ * metadata.tdb lock is taken out above, as it is the best we can do >+ * right now. > */ > ret = ldb_next_read_lock(module); > if (ret != LDB_SUCCESS) { >@@ -1455,12 +1506,8 @@ int partition_read_lock(struct ldb_module *module) > } > > /* >- * The top level DB (sam.ldb) lock is not >- * enough to block another process in prepare_commit(), >- * because prepare_commit() is a no-op, if nothing >- * was changed in the specific backend. >- * >- * That means the following per partition locks are required. >+ * The following per partition locks are required mostly because TDB >+ * and MDB require locks before reads are permitted. > */ > for (i=0; data && data->partitions && data->partitions[i]; i++) { > if ((module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING)) { >@@ -1485,15 +1532,6 @@ int partition_read_lock(struct ldb_module *module) > goto failed; > } > >- /* >- * Because in prepare_commit this must come last, to ensure >- * lock ordering we have to do this last here also >- */ >- ret = partition_metadata_read_lock(module); >- if (ret != LDB_SUCCESS) { >- goto failed; >- } >- > return LDB_SUCCESS; > > failed: >@@ -1531,10 +1569,9 @@ int partition_read_unlock(struct ldb_module *module) > struct partition_private_data); > > /* >- * This order must be similar to partition_{end,del}_trans() >- * the metadata partition (sam.ldb) unlock must be at the end. >+ * Order of read_unlock calls must be the reverse of that in >+ * partition_start_trans. See comment in that function for detail. > */ >- > for (i=0; data && data->partitions && data->partitions[i]; i++) { > if ((module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING)) { > ldb_debug(ldb, LDB_DEBUG_TRACE, >@@ -1584,10 +1621,6 @@ int partition_read_unlock(struct ldb_module *module) > } > } > >- /* >- * Because in prepare_commit this must come last, to ensure >- * lock ordering we have to do this last here also >- */ > ret = partition_metadata_read_unlock(module); > > /* >-- >2.17.1 > > >From 29fa37b717cc83080ed9eb50345370b8f40d7ce7 Mon Sep 17 00:00:00 2001 >From: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Date: Mon, 15 Jul 2019 13:32:41 +1200 >Subject: [PATCH 004/376] partition: reversing partition unlocking > >Unlock partition databases in the reverse order from which they were >acquired. This is separated from the previous commit for future >bisecting purposes, since the last commit was made to fix specific CI >failures, while this one is a speculative fix made based on code >inspection. > >Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 6c691bf84e41b1edd3228c219f7a94e108795d28) >--- > source4/dsdb/samdb/ldb_modules/partition.c | 125 ++++++++++++--------- > 1 file changed, 72 insertions(+), 53 deletions(-) > >diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c >index 93fa129c14e..e34ba35680b 100644 >--- a/source4/dsdb/samdb/ldb_modules/partition.c >+++ b/source4/dsdb/samdb/ldb_modules/partition.c >@@ -1165,9 +1165,11 @@ int partition_prepare_commit(struct ldb_module *module) > int partition_end_trans(struct ldb_module *module) > { > int ret, ret2; >- unsigned int i; >+ int i; >+ struct ldb_context *ldb = ldb_module_get_ctx(module); > struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module), > struct partition_private_data); >+ bool trace = module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING; > > ret = LDB_SUCCESS; > >@@ -1182,21 +1184,28 @@ int partition_end_trans(struct ldb_module *module) > * Order of end_trans calls must be the reverse of that in > * partition_start_trans. See comment in that function for detail. > */ >- for (i=0; data && data->partitions && data->partitions[i]; i++) { >- if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) { >- ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> %s", >- ldb_dn_get_linearized(data->partitions[i]->ctrl->dn)); >- } >- ret2 = ldb_next_end_trans(data->partitions[i]->module); >- if (ret2 != LDB_SUCCESS) { >- ldb_asprintf_errstring(ldb_module_get_ctx(module), "end_trans error on %s: %s", >- ldb_dn_get_linearized(data->partitions[i]->ctrl->dn), >- ldb_errstring(ldb_module_get_ctx(module))); >- ret = ret2; >+ if (data && data->partitions) { >+ for (i=0; data->partitions[i]; i++);; >+ for (i--; i>=0; i--) { >+ struct dsdb_partition *p = data->partitions[i]; >+ if (trace) { >+ ldb_debug(ldb, >+ LDB_DEBUG_TRACE, >+ "partition_end_trans() -> %s", >+ ldb_dn_get_linearized(p->ctrl->dn)); >+ } >+ ret2 = ldb_next_end_trans(p->module); >+ if (ret2 != LDB_SUCCESS) { >+ ldb_asprintf_errstring(ldb, >+ "end_trans error on %s: %s", >+ ldb_dn_get_linearized(p->ctrl->dn), >+ ldb_errstring(ldb)); >+ ret = ret2; >+ } > } > } > >- if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) { >+ if (trace) { > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> (metadata partition)"); > } > ret2 = ldb_next_end_trans(module); >@@ -1216,31 +1225,38 @@ int partition_end_trans(struct ldb_module *module) > int partition_del_trans(struct ldb_module *module) > { > int ret, final_ret = LDB_SUCCESS; >- unsigned int i; >+ int i; >+ struct ldb_context *ldb = ldb_module_get_ctx(module); > struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module), > struct partition_private_data); >+ bool trace = module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING; > > /* > * Order of del_trans calls must be the reverse of that in > * partition_start_trans. See comment in that function for detail. > */ >- for (i=0; data && data->partitions && data->partitions[i]; i++) { >- if (ldb_module_flags(ldb_module_get_ctx(module)) & >- LDB_FLG_ENABLE_TRACING) { >- ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_del_trans() -> %s", >- ldb_dn_get_linearized(data->partitions[i]->ctrl->dn)); >- } >- ret = ldb_next_del_trans(data->partitions[i]->module); >- if (ret != LDB_SUCCESS) { >- ldb_asprintf_errstring(ldb_module_get_ctx(module), "del_trans error on %s: %s", >- ldb_dn_get_linearized(data->partitions[i]->ctrl->dn), >- ldb_errstring(ldb_module_get_ctx(module))); >- final_ret = ret; >+ if (data && data->partitions) { >+ for (i=0; data->partitions[i]; i++);; >+ for (i--; i>=0; i--) { >+ struct dsdb_partition *p = data->partitions[i]; >+ if (trace) { >+ ldb_debug(ldb, >+ LDB_DEBUG_TRACE, >+ "partition_del_trans() -> %s", >+ ldb_dn_get_linearized(p->ctrl->dn)); >+ } >+ ret = ldb_next_del_trans(p->module); >+ if (ret != LDB_SUCCESS) { >+ ldb_asprintf_errstring(ldb, >+ "del_trans error on %s: %s", >+ ldb_dn_get_linearized(p->ctrl->dn), >+ ldb_errstring(ldb)); >+ final_ret = ret; >+ } > } >- } >+ } > >- if (ldb_module_flags(ldb_module_get_ctx(module)) & >- LDB_FLG_ENABLE_TRACING) { >+ if (trace) { > ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_del_trans() -> (metadata partition)"); > } > ret = ldb_next_del_trans(module); >@@ -1567,39 +1583,42 @@ int partition_read_unlock(struct ldb_module *module) > struct partition_private_data *data = \ > talloc_get_type(ldb_module_get_private(module), > struct partition_private_data); >+ bool trace = module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING; > > /* > * Order of read_unlock calls must be the reverse of that in > * partition_start_trans. See comment in that function for detail. > */ >- for (i=0; data && data->partitions && data->partitions[i]; i++) { >- if ((module && ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING)) { >- ldb_debug(ldb, LDB_DEBUG_TRACE, >- "partition_read_unlock() -> %s", >- ldb_dn_get_linearized( >- data->partitions[i]->ctrl->dn)); >- } >- ret2 = ldb_next_read_unlock(data->partitions[i]->module); >- if (ret2 != LDB_SUCCESS) { >- ldb_debug_set(ldb, >- LDB_DEBUG_FATAL, >- "Failed to lock db: %s / %s for %s", >- ldb_errstring(ldb), >- ldb_strerror(ret), >- ldb_dn_get_linearized( >- data->partitions[i]->ctrl->dn)); >- >- /* >- * Don't overwrite the original failure code >- * if there was one >- */ >- if (ret == LDB_SUCCESS) { >- ret = ret2; >+ if (data && data->partitions) { >+ for (i=0; data->partitions[i]; i++);; >+ for (i--; i>=0; i--) { >+ struct dsdb_partition *p = data->partitions[i]; >+ if (trace) { >+ ldb_debug(ldb, LDB_DEBUG_TRACE, >+ "partition_read_unlock() -> %s", >+ ldb_dn_get_linearized(p->ctrl->dn)); >+ } >+ ret2 = ldb_next_read_unlock(p->module); >+ if (ret2 != LDB_SUCCESS) { >+ ldb_debug_set(ldb, >+ LDB_DEBUG_FATAL, >+ "Failed to lock db: %s / %s for %s", >+ ldb_errstring(ldb), >+ ldb_strerror(ret), >+ ldb_dn_get_linearized(p->ctrl->dn)); >+ >+ /* >+ * Don't overwrite the original failure code >+ * if there was one >+ */ >+ if (ret == LDB_SUCCESS) { >+ ret = ret2; >+ } > } > } > } > >- if (ldb_module_flags(ldb) & LDB_FLG_ENABLE_TRACING) { >+ if (trace) { > ldb_debug(ldb, LDB_DEBUG_TRACE, > "partition_read_unlock() -> (metadata partition)"); > } >-- >2.17.1 > > >From f2c40f4d41a4729bf31534ce34261d70c5dd0071 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Thu, 18 Jul 2019 14:50:57 +1200 >Subject: [PATCH 005/376] gp_inf: Read/write files with a UTF-16LE BOM in > GptTmpl.inf > >Regression caused by 16596842a62bec0a9d974c48d64000e3c079254e > >[MS-GPSB] 2.2 Message Syntax says that you have to write a BOM which I >didn't do up until this patch. UTF-16 as input encoding was marked much >higher up in the inheritance tree, which got overriden with the Python 3 >fixes. I've now marked the encoding much more obviously for this file. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14004 > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >Autobuild-User(master): Gary Lockyer <gary@samba.org> >Autobuild-Date(master): Fri Jul 19 02:20:47 UTC 2019 on sn-devel-184 > >(cherry picked from commit 0bcfc550b1a902e3a6a766b06603ac9285d0ff63) >--- > python/samba/gp_parse/gp_inf.py | 9 ++++++--- > .../SecEdit/GptTmpl.inf.SAMBABACKUP | Bin 2580 -> 2582 bytes > 2 files changed, 6 insertions(+), 3 deletions(-) > >diff --git a/python/samba/gp_parse/gp_inf.py b/python/samba/gp_parse/gp_inf.py >index 79e28159f1f..a3c828fa82d 100644 >--- a/python/samba/gp_parse/gp_inf.py >+++ b/python/samba/gp_parse/gp_inf.py >@@ -29,11 +29,11 @@ from samba.gp_parse import GPParser > # [MS-GPSB] Security Protocol Extension > class GptTmplInfParser(GPParser): > sections = None >- encoding = 'utf-16le' >+ encoding = 'utf-16' >+ output_encoding = 'utf-16le' > > class AbstractParam: > __metaclass__ = ABCMeta >- encoding = 'utf-16le' > > def __init__(self): > self.param_list = [] >@@ -333,7 +333,10 @@ class GptTmplInfParser(GPParser): > > def write_binary(self, filename): > with codecs.open(filename, 'wb+', >- self.encoding) as f: >+ self.output_encoding) as f: >+ # Write the byte-order mark >+ f.write(u'\ufeff') >+ > for s in self.sections: > self.sections[s].write_section(s, f) > >diff --git a/source4/selftest/provisions/generalized-gpo-backup/policy/{1E1DC8EA-390C-4800-B327-98B56A0AEA5D}/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf.SAMBABACKUP b/source4/selftest/provisions/generalized-gpo-backup/policy/{1E1DC8EA-390C-4800-B327-98B56A0AEA5D}/Machine/Microsoft/Windows NT/SecEdit/GptTmpl.inf.SAMBABACKUP >index 18c58a7baa9566be4977086640f4ad8c3e4c38a7..8de94078e703e9adf222dfc0bd4bfff31e797bbd 100644 >GIT binary patch >delta 10 >RcmbOtGEIc(|Gy0)TmTmX1Rwwa > >delta 8 >PcmbOxGDTz~lL!|83>*R^ > >-- >2.17.1 > > >From 98051741ea5069b0e6fb7274cd1959460c7f95a1 Mon Sep 17 00:00:00 2001 >From: David Disseldorp <ddiss@samba.org> >Date: Mon, 8 Jul 2019 13:42:50 +0200 >Subject: [PATCH 006/376] WHATSNEW: add CephFS Snapshot Integration section > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=14039 > >Signed-off-by: David Disseldorp <ddiss@samba.org> >Reviewed-by: Aurelien Aptel <aaptel@suse.com> >--- > WHATSNEW.txt | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index b07e9eba778..fce43f55cfa 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -59,8 +59,8 @@ worker processes at startup and share the client connections amongst these > workers. The number of worker processes can be configured by the 'prefork > children' setting in the smb.conf (the default is 4). > >-Authentication Logging. >------------------------ >+Authentication Logging >+---------------------- > > Winbind now logs PAM_AUTH and NTLM_AUTH events, a new attribute "logonId" has > been added to the Authentication JSON log messages. This contains a random >@@ -254,6 +254,12 @@ CTDB changes > swap) utilisation using the existing CTDB_MONITOR_MEMORY_USAGE > script configuration variable. > >+CephFS Snapshot Integration >+--------------------------- >+ >+CephFS snapshots can now be exposed as previous file versions using the new >+ceph_snapshots VFS module. See the vfs_ceph_snapshots(8) man page for details. >+ > > REMOVED FEATURES > ================ >-- >2.17.1 > > >From 122d7afb50e7d9b67954979b38d4f1b168dfde97 Mon Sep 17 00:00:00 2001 >From: Aurelien Aptel <aaptel@suse.com> >Date: Tue, 9 Jul 2019 23:55:30 +0200 >Subject: [PATCH 007/376] WHATSNEW: document new debug encryption smb.conf > param > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=14039 > >Signed-off-by: Aurelien Aptel <aaptel@suse.com> >Reviewed-by: David Disseldorp <ddiss@samba.org> >--- > WHATSNEW.txt | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index fce43f55cfa..e91ad51c71b 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -312,6 +312,7 @@ smb.conf changes > mangled names Changed default illegal > web port Removed > fruit:zero_file_id Changed default False >+ debug encryption New: dump encryption keys False > > > KNOWN ISSUES >-- >2.17.1 > > >From b95186a533201b8eeeb49a073e65e60a3a57bf75 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Mon, 8 Jul 2019 16:59:33 +1200 >Subject: [PATCH 008/376] ldap_server: Regression in > 0559430ab6e5c48d6e853fda0d8b63f2e149015c > >Extended DN requests seem to have been incorrectly handled. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14029 > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >Autobuild-User(master): Gary Lockyer <gary@samba.org> >Autobuild-Date(master): Thu Jul 11 05:25:26 UTC 2019 on sn-devel-184 > >(cherry picked from commit 9f6b87d3f6cc9930d75c1f8d38ad4f5a37da34ab) >--- > source4/ldap_server/ldap_backend.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c >index c6a65122ab0..bf724335a25 100644 >--- a/source4/ldap_server/ldap_backend.c >+++ b/source4/ldap_server/ldap_backend.c >@@ -826,6 +826,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call) > } else { > extended_type = 0; > } >+ callback_ctx->extended_type = extended_type; > } > > notification_control = ldb_request_get_control(lreq, LDB_CONTROL_NOTIFICATION_OID); >-- >2.17.1 > > >From dd36cafdb96e37eb8ee6b55feb3233dc07558b41 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 31 Jul 2019 01:08:23 +0000 >Subject: [PATCH 009/376] tldap: Make memcpy of no controls safe > >Static analyzers sometimes complain about this case. > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14029 >(cherry picked from commit e5452a37425484a95f90604a3e58e8a731460793) >--- > source3/lib/tldap_util.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c >index 152942dab2c..bdf8eb031a5 100644 >--- a/source3/lib/tldap_util.c >+++ b/source3/lib/tldap_util.c >@@ -588,7 +588,9 @@ struct tldap_control *tldap_add_control(TALLOC_CTX *mem_ctx, > if (result == NULL) { > return NULL; > } >- memcpy(result, ctrls, sizeof(struct tldap_control) * num_ctrls); >+ if (num_ctrls > 0) { >+ memcpy(result, ctrls, sizeof(struct tldap_control) * num_ctrls); >+ } > result[num_ctrls] = *ctrl; > return result; > } >-- >2.17.1 > > >From 23f8a8ee71b6aa2b88174e5d9556508ae48e733e Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 31 Jul 2019 13:39:13 +1200 >Subject: [PATCH 010/376] tldap: Paged searches fail when they get to the end > >The normal case hit the goto label, and should have just returned. > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14029 >(cherry picked from commit bff466943e01540b4d3210392e0fd5b1c882c0b9) >--- > source3/lib/tldap_util.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source3/lib/tldap_util.c b/source3/lib/tldap_util.c >index bdf8eb031a5..1b86962a32e 100644 >--- a/source3/lib/tldap_util.c >+++ b/source3/lib/tldap_util.c >@@ -810,7 +810,8 @@ static void tldap_search_paged_done(struct tevent_req *subreq) > } > tevent_req_set_callback(subreq, tldap_search_paged_done, req); > >- err: >+ return; >+err: > > TALLOC_FREE(asn1); > tevent_req_ldap_error(req, TLDAP_DECODING_ERROR); >-- >2.17.1 > > >From a1d0ce447e782b88386189969afa46f2dc4ed43a Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 31 Jul 2019 15:29:07 +1200 >Subject: [PATCH 011/376] tests/tldap: Actually check the paging return code > >The test never worked correctly because the code was overlooked. It was >also the case that the connection was never authenticated, and so an >LDAP BIND call has now been added. > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14029 >(cherry picked from commit 85a7b594c56f7729bdfa194fee9299a08f6b4785) >--- > source3/torture/torture.c | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index 2cb32efea46..20a7459b4db 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -11286,6 +11286,8 @@ static bool run_shortname_test(int dummy) > return correct; > } > >+TLDAPRC callback_code; >+ > static void pagedsearch_cb(struct tevent_req *req) > { > TLDAPRC rc; >@@ -11296,6 +11298,7 @@ static void pagedsearch_cb(struct tevent_req *req) > if (!TLDAP_RC_IS_SUCCESS(rc)) { > d_printf("tldap_search_paged_recv failed: %s\n", > tldap_rc2string(rc)); >+ callback_code = rc; > return; > } > if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) { >@@ -11360,6 +11363,18 @@ static bool run_tldap(int dummy) > return false; > } > >+ rc = tldap_gensec_bind(ld, torture_creds, "ldap", host, NULL, >+ loadparm_init_s3(talloc_tos(), >+ loadparm_s3_helpers()), >+ GENSEC_FEATURE_SIGN | GENSEC_FEATURE_SEAL); >+ >+ if (!TLDAP_RC_IS_SUCCESS(rc)) { >+ d_printf("tldap_gensec_bind failed\n"); >+ return false; >+ } >+ >+ callback_code = TLDAP_SUCCESS; >+ > req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn, > TLDAP_SCOPE_SUB, "(objectclass=*)", > NULL, 0, 0, >@@ -11374,6 +11389,14 @@ static bool run_tldap(int dummy) > > TALLOC_FREE(req); > >+ rc = callback_code; >+ >+ if (!TLDAP_RC_IS_SUCCESS(rc)) { >+ d_printf("tldap_search with paging failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ > /* test search filters against rootDSE */ > filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))" > "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))"; >-- >2.17.1 > > >From 636f7dedd40d1f357d0b0799496fabeb82e73450 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 31 Jul 2019 01:14:42 +0000 >Subject: [PATCH 012/376] tests/ldap: Use TLDAP to check the extended DN return > >Tests commit 9f6b87d3f6cc9930d75c1f8d38ad4f5a37da34ab > >To run: make test TESTS="samba3.smbtorture_s3.plain.TLDAP" > >Reverting the above commit makes this test fail: > >'GUID format in control (no hyphens) doesn't match output >tldap_search with extended dn (no val) failed: LDAP error 0 (TLDAP_SUCCESS), >TEST TLDAP FAILED!' > >This behaviour couldn't be tested via LDB libraries because they never >deal with the underlying DN string. > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14029 > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Thu Aug 1 06:20:28 UTC 2019 on sn-devel-184 > >(adapted from commit 464fef34d1d047d73be347cd446b74e0f5eb2370) >--- > source3/torture/torture.c | 155 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 155 insertions(+) > >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index 20a7459b4db..f26c634b7a7 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -26,6 +26,7 @@ > #include "libcli/security/security.h" > #include "tldap.h" > #include "tldap_util.h" >+#include "tldap_gensec_bind.h" > #include "../librpc/gen_ndr/svcctl.h" > #include "../lib/util/memcache.h" > #include "nsswitch/winbind_client.h" >@@ -45,6 +46,9 @@ > #include "lib/util/base64.h" > #include "lib/util/time.h" > #include "lib/gencache.h" >+#include "lib/util/asn1.h" >+#include "lib/param/param.h" >+#include "auth/gensec/gensec.h" > > #include <gnutls/gnutls.h> > #include <gnutls/crypto.h> >@@ -11313,6 +11317,134 @@ static void pagedsearch_cb(struct tevent_req *req) > TALLOC_FREE(msg); > } > >+enum tldap_extended_val { >+ EXTENDED_ZERO = 0, >+ EXTENDED_ONE = 1, >+ EXTENDED_NONE = 2, >+}; >+ >+/* >+ * Construct an extended dn control with either no value, 0 or 1 >+ * >+ * No value and 0 are equivalent (non-hyphenated GUID) >+ * 1 has the hyphenated GUID >+ */ >+static struct tldap_control * >+tldap_build_extended_control(enum tldap_extended_val val) >+{ >+ struct tldap_control empty_control; >+ struct asn1_data *data; >+ >+ ZERO_STRUCT(empty_control); >+ >+ if (val != EXTENDED_NONE) { >+ data = asn1_init(talloc_tos()); >+ >+ if (!data) { >+ return NULL; >+ } >+ >+ if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) { >+ return NULL; >+ } >+ >+ if (!asn1_write_Integer(data, (int)val)) { >+ return NULL; >+ } >+ >+ if (!asn1_pop_tag(data)) { >+ return NULL; >+ } >+ >+ if (!asn1_blob(data, &empty_control.value)) { >+ return NULL; >+ } >+ } >+ >+ empty_control.oid = "1.2.840.113556.1.4.529"; >+ empty_control.critical = true; >+ >+ return tldap_add_control(talloc_tos(), NULL, 0, &empty_control); >+ >+} >+ >+static bool tldap_test_dn_guid_format(struct tldap_context *ld, const char *basedn, >+ enum tldap_extended_val control_val) >+{ >+ struct tldap_control *control = tldap_build_extended_control(control_val); >+ char *dn = NULL; >+ struct tldap_message **msg; >+ TLDAPRC rc; >+ >+ rc = tldap_search(ld, basedn, TLDAP_SCOPE_BASE, >+ "(objectClass=*)", NULL, 0, 0, >+ control, 1, NULL, >+ 0, 0, 0, 0, talloc_tos(), &msg); >+ if (!TLDAP_RC_IS_SUCCESS(rc)) { >+ d_printf("tldap_search for domain DN failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ >+ if (!tldap_entry_dn(msg[0], &dn)) { >+ d_printf("tldap_search domain DN fetch failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ >+ d_printf("%s\n", dn); >+ { >+ uint32_t time_low; >+ uint32_t time_mid, time_hi_and_version; >+ uint32_t clock_seq[2]; >+ uint32_t node[6]; >+ char next; >+ >+ switch (control_val) { >+ case EXTENDED_NONE: >+ case EXTENDED_ZERO: >+ /* >+ * When reading GUIDs with hyphens, scanf will treat >+ * hyphen as a hex character (and counts as part of the >+ * width). This creates leftover GUID string which we >+ * check will for with 'next' and closing '>'. >+ */ >+ if (12 == sscanf(dn, "<GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x>%c", >+ &time_low, &time_mid, >+ &time_hi_and_version, &clock_seq[0], >+ &clock_seq[1], &node[0], &node[1], >+ &node[2], &node[3], &node[4], >+ &node[5], &next)) { >+ /* This GUID is good */ >+ } else { >+ d_printf("GUID format in control (no hyphens) doesn't match output\n"); >+ return false; >+ } >+ >+ break; >+ case EXTENDED_ONE: >+ if (12 == sscanf(dn, >+ "<GUID=%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x>%c", >+ &time_low, &time_mid, >+ &time_hi_and_version, &clock_seq[0], >+ &clock_seq[1], &node[0], &node[1], >+ &node[2], &node[3], &node[4], >+ &node[5], &next)) { >+ /* This GUID is good */ >+ } else { >+ d_printf("GUID format in control (with hyphens) doesn't match output\n"); >+ return false; >+ } >+ >+ break; >+ default: >+ return false; >+ } >+ } >+ >+ return true; >+} >+ > static bool run_tldap(int dummy) > { > struct tldap_context *ld; >@@ -11410,6 +11542,29 @@ static bool run_tldap(int dummy) > return false; > } > >+ /* >+ * Tests to check for regression of: >+ * >+ * https://bugzilla.samba.org/show_bug.cgi?id=14029 >+ * >+ * TLDAP used here to pick apart the original string DN (with GUID) >+ */ >+ if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_NONE)) { >+ d_printf("tldap_search with extended dn (no val) failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ZERO)) { >+ d_printf("tldap_search with extended dn (0) failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ if (!tldap_test_dn_guid_format(ld, basedn, EXTENDED_ONE)) { >+ d_printf("tldap_search with extended dn (1) failed: %s\n", >+ tldap_errstr(talloc_tos(), ld, rc)); >+ return false; >+ } >+ > TALLOC_FREE(ld); > return true; > } >-- >2.17.1 > > >From 816053b7bba894aa217a895925621801f0d17681 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 24 Jul 2019 11:00:01 +1200 >Subject: [PATCH 013/376] join: Use a specific attribute order for the > DsAddEntry nTDSDSA object > >Joining a Windows domain can throw an error if the HasMasterNCs >attribute occurs before msDS-HasMasterNCs. This patch changes the >attribute order so that msDS-HasMasterNCs is always first. > >Previously on python2, the dictionary hash order was arbitrary but >constant. By luck, msDS-HasMasterNCs was always before HasMasterNCs, so >we never noticed any problem. With python3, the dictionary hash order >now changes everytime you run the command, so the order is >unpredictable. > >To enforce a order, we can change to use an OrderedDict, which will >return the keys in the order they're added. > >I've asked Microsoft to clarify the protocol requirement here WRT >attribute order. However, in the meantime we may as well fix the problem >for users. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14046 >RN: When trying to join a Windows domain (with functional level 2008R2) >as an AD domain controller, the 'samba-tool domain join' command could >throw a python exception: 'RuntimeError ("DsAddEntry failed")'. When >this problem occurred, you would also see the message "DsAddEntry failed >with status WERR_ACCESS_DENIED info (8363, 'WERR_DS_NO_CROSSREF_FOR_NC')" >in the command output. This issue has now been resolved. Note that this >problem would only occur on Samba v4.10 when using the Python3 packages. > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Wed Jul 24 04:18:21 UTC 2019 on sn-devel-184 > >(cherry picked from commit 256684c7a86301d26d6cf7298fb70e647bf45cf5) >--- > python/samba/join.py | 23 ++++++++++++++++------- > 1 file changed, 16 insertions(+), 7 deletions(-) > >diff --git a/python/samba/join.py b/python/samba/join.py >index ac4346c62a3..40920f4f8e5 100644 >--- a/python/samba/join.py >+++ b/python/samba/join.py >@@ -48,6 +48,7 @@ import time > import re > import os > import tempfile >+from collections import OrderedDict > from samba.compat import text_type > from samba.compat import get_string > from samba.netcmd import CommandError >@@ -555,11 +556,14 @@ class DCJoinContext(object): > '''return the ntdsdsa object to add''' > > print("Adding %s" % ctx.ntds_dn) >- rec = { >- "dn": ctx.ntds_dn, >- "objectclass": "nTDSDSA", >- "systemFlags": str(samba.dsdb.SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE), >- "dMDLocation": ctx.schema_dn} >+ >+ # When joining Windows, the order of certain attributes (mostly only >+ # msDS-HasMasterNCs and HasMasterNCs) seems to matter >+ rec = OrderedDict([ >+ ("dn", ctx.ntds_dn), >+ ("objectclass", "nTDSDSA"), >+ ("systemFlags", str(samba.dsdb.SYSTEM_FLAG_DISALLOW_MOVE_ON_DELETE)), >+ ("dMDLocation", ctx.schema_dn)]) > > nc_list = [ctx.base_dn, ctx.config_dn, ctx.schema_dn] > >@@ -575,12 +579,17 @@ class DCJoinContext(object): > rec["options"] = "37" > else: > rec["objectCategory"] = "CN=NTDS-DSA,%s" % ctx.schema_dn >+ >+ # Note that Windows seems to have an undocumented requirement that >+ # the msDS-HasMasterNCs attribute occurs before HasMasterNCs >+ if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: >+ rec["msDS-HasMasterNCs"] = ctx.full_nc_list >+ > rec["HasMasterNCs"] = [] > for nc in nc_list: > if nc in ctx.full_nc_list: > rec["HasMasterNCs"].append(nc) >- if ctx.behavior_version >= samba.dsdb.DS_DOMAIN_FUNCTION_2003: >- rec["msDS-HasMasterNCs"] = ctx.full_nc_list >+ > rec["options"] = "1" > rec["invocationId"] = ndr_pack(ctx.invocation_id) > >-- >2.17.1 > > >From 8a09ea3c70f95a577ed42123ebe8d3ab26f2c39d Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 24 Jul 2019 15:18:40 +1200 >Subject: [PATCH 014/376] netcmd: Allow drs replicate --local to create > partitions > >Currently, neither the offline (--local) or online (normal replica sync) >methods allow partition creation post-join. This overrides the Python >default to not create the DB, which allows TDB + MDB to work. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14051 > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit d90ccce59754bc833027c06683afac25f7a8d474) >--- > python/samba/netcmd/drs.py | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/python/samba/netcmd/drs.py b/python/samba/netcmd/drs.py >index 739498cca1b..9d6e8087e87 100644 >--- a/python/samba/netcmd/drs.py >+++ b/python/samba/netcmd/drs.py >@@ -449,8 +449,10 @@ class cmd_drs_replicate(Command): > self.server = SOURCE_DC > drsuapi_connect(self) > >+ # Override the default flag LDB_FLG_DONT_CREATE_DB > self.local_samdb = SamDB(session_info=system_session(), url=None, >- credentials=self.creds, lp=self.lp) >+ credentials=self.creds, lp=self.lp, >+ flags=0) > > self.samdb = SamDB(url="ldap://%s" % self.server, > session_info=system_session(), >-- >2.17.1 > > >From c7a5694f4f81676f89969464645c9ff021680eb2 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 24 Jul 2019 15:13:43 +1200 >Subject: [PATCH 015/376] tests: Add samba_upgradedns to the list of possible > cmds > >This will be used to test the replication scenario with no DNS partitions > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14051 > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7d2875bd70cf727730be8dc705bfd01eacaaaa6f) >--- > python/samba/tests/__init__.py | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py >index c5c212ef829..fef21d261ca 100644 >--- a/python/samba/tests/__init__.py >+++ b/python/samba/tests/__init__.py >@@ -404,6 +404,7 @@ class BlackboxTestCase(TestCaseInTempDir): > > python_cmds = ["samba-tool", > "samba_dnsupdate", >+ "samba_upgradedns", > "script/traffic_replay", > "script/traffic_learner"] > >-- >2.17.1 > > >From 97a742fe7617d153e38aac5ad6c887c79a6e2447 Mon Sep 17 00:00:00 2001 >From: Garming Sam <garming@catalyst.net.nz> >Date: Wed, 24 Jul 2019 14:53:33 +1200 >Subject: [PATCH 016/376] tests/drs_no_dns: Check dbcheck and ldapcmp pass > >When joining a DC without DNS partitions, make sure that the alternate >flow of creating them afterwards results in a database with everything >that is necessary. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14051 >RN: Allow a DC join without DNS partitions, to add them later > >Signed-off-by: Garming Sam <garming@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 35c54007e6183829d9d85a24b3bd95f469739ad3) >--- > source4/selftest/tests.py | 7 + > .../drs/python/samba_tool_drs_no_dns.py | 183 ++++++++++++++++++ > 2 files changed, 190 insertions(+) > create mode 100644 source4/torture/drs/python/samba_tool_drs_no_dns.py > >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 1a7e8c757f0..bf3dd98cbef 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -949,6 +949,13 @@ for env in ['backupfromdc', 'offlinebackupdc', 'restoredc', 'renamedc', > plantestsuite("samba4.blackbox.join_ldapcmp", env, > ["PYTHON=%s" % python, os.path.join(bbdir, "join_ldapcmp.sh")]) > >+env = 'backupfromdc' >+planoldpythontestsuite("%s:local" % env, "samba_tool_drs_no_dns", >+ extra_path=[os.path.join(samba4srcdir, 'torture/drs/python')], >+ name="samba4.drs.samba_tool_drs_no_dns.python(%s)" % env, >+ environ={'DC1': '$DC_SERVER', 'DC2': '$DC_SERVER'}, >+ extra_args=['-U$DOMAIN/$DC_USERNAME%$DC_PASSWORD']) >+ > plantestsuite_loadlist("samba4.ldap.rodc.python(rodc)", "rodc", > [python, > os.path.join(DSDB_PYTEST_DIR, "rodc.py"), >diff --git a/source4/torture/drs/python/samba_tool_drs_no_dns.py b/source4/torture/drs/python/samba_tool_drs_no_dns.py >new file mode 100644 >index 00000000000..b9cab49e82b >--- /dev/null >+++ b/source4/torture/drs/python/samba_tool_drs_no_dns.py >@@ -0,0 +1,183 @@ >+# Blackbox tests for "samba-tool drs" command >+# Copyright (C) Kamen Mazdrashki <kamenim@samba.org> 2011 >+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2017 >+# Copyright (C) Catalyst.Net Ltd 2019 >+# >+# This program is free software; you can redistribute it and/or modify >+# it under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# This program is distributed in the hope that it will be useful, >+# but WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with this program. If not, see <http://www.gnu.org/licenses/>. >+# >+ >+""" >+Blackbox tests for samba-tool drs with no DNS partitions >+ >+Adapted from samba_tool_drs.py >+""" >+ >+import samba.tests >+import shutil >+import os >+import ldb >+import drs_base >+ >+from samba.tests import BlackboxProcessError >+from samba.compat import get_string >+ >+ >+class SambaToolDrsNoDnsTests(drs_base.DrsBaseTestCase): >+ """Blackbox test case for samba-tool drs.""" >+ >+ def setUp(self): >+ super(SambaToolDrsNoDnsTests, self).setUp() >+ >+ self.dc1 = samba.tests.env_get_var_value("DC1") >+ >+ creds = self.get_credentials() >+ self.cmdline_creds = "-U%s/%s%%%s" % (creds.get_domain(), >+ creds.get_username(), creds.get_password()) >+ >+ def tearDown(self): >+ self._enable_inbound_repl(self.dnsname_dc1) >+ >+ try: >+ shutil.rmtree(os.path.join(self.tempdir, "private")) >+ shutil.rmtree(os.path.join(self.tempdir, "etc")) >+ shutil.rmtree(os.path.join(self.tempdir, "msg.lock")) >+ os.remove(os.path.join(self.tempdir, "names.tdb")) >+ shutil.rmtree(os.path.join(self.tempdir, "state")) >+ shutil.rmtree(os.path.join(self.tempdir, "bind-dns")) >+ except Exception: >+ pass >+ >+ super(SambaToolDrsNoDnsTests, self).tearDown() >+ >+ def _get_rootDSE(self, dc, ldap_only=True): >+ samdb = samba.tests.connect_samdb(dc, lp=self.get_loadparm(), >+ credentials=self.get_credentials(), >+ ldap_only=ldap_only) >+ return samdb.search(base="", scope=samba.tests.ldb.SCOPE_BASE)[0], samdb >+ >+ def test_samba_tool_replicate_local_no_dns_tdb(self): >+ self.backend = 'tdb' >+ self._test_samba_tool_replicate_local_no_dns() >+ >+ def test_samba_tool_replicate_local_no_dns_mdb(self): >+ self.backend = 'mdb' >+ self._test_samba_tool_replicate_local_no_dns() >+ >+ def _test_samba_tool_replicate_local_no_dns(self): >+ """Check we can provision a database without DNS partitions >+ (and then add them afterwards).""" >+ >+ server_rootdse, _ = self._get_rootDSE(self.dc1) >+ nc_name = server_rootdse["defaultNamingContext"] >+ server_ldap_service_name = str(server_rootdse["ldapServiceName"][0]) >+ server_realm = server_ldap_service_name.split(":")[0] >+ creds = self.get_credentials() >+ >+ # We have to give it a different netbiosname every time >+ # it runs, otherwise the collision causes strange issues >+ # to happen. This should be different on different environments. >+ netbiosname = "dns" + self.backend + self.dc1 >+ if len(netbiosname) > 15: >+ netbiosname = netbiosname[:15] >+ >+ out = self.check_output("samba-tool domain join %s dc --server=%s %s --targetdir=%s --option=netbiosname=%s %s --backend-store=%s" >+ % (server_realm, self.dc1, self.cmdline_creds, >+ self.tempdir, netbiosname, >+ "--dns-backend=NONE", >+ self.backend)) >+ >+ new_dc_config_file = os.path.join(self.tempdir, "etc", "smb.conf") >+ new_dc_sam = os.path.join(self.tempdir, "private", "sam.ldb") >+ >+ forestdns_dn = ldb.binary_encode('DC=ForestDNSZones,' + str(nc_name)) >+ domaindns_dn = ldb.binary_encode('DC=DomainDNSZones,' + str(nc_name)) >+ >+ self.check_output("samba-tool drs replicate --local %s %s %s %s -s %s --full-sync" >+ % ("invalid", self.dc1, forestdns_dn, >+ self.cmdline_creds, new_dc_config_file)) >+ >+ self.check_output("samba-tool drs replicate --local %s %s %s %s -s %s --full-sync" >+ % ("invalid", self.dc1, domaindns_dn, >+ self.cmdline_creds, new_dc_config_file)) >+ >+ server_rootdse, samdb = self._get_rootDSE("ldb://" + new_dc_sam, ldap_only=False) >+ server_ds_name = ldb.binary_encode(server_rootdse["dsServiceName"][0].decode('utf-8')) >+ >+ # Show that Has-Master-NCs is fixed by samba_upgradedns >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % forestdns_dn) >+ self.assertEquals(len(res), 0) >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % domaindns_dn) >+ self.assertEquals(len(res), 0) >+ >+ self.check_output("samba_upgradedns -s %s" % (new_dc_config_file)) >+ >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % forestdns_dn) >+ self.assertEquals(len(res), 1) >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % domaindns_dn) >+ self.assertEquals(len(res), 1) >+ >+ # Show that replica locations is fixed by dbcheck >+ res = samdb.search(controls=["search_options:1:2"], >+ expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" >+ % (server_ds_name, forestdns_dn)) >+ self.assertEquals(len(res), 0) >+ res = samdb.search(controls=["search_options:1:2"], >+ expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" >+ % (server_ds_name, domaindns_dn)) >+ self.assertEquals(len(res), 0) >+ >+ try: >+ # This fixes any forward-link-backward-link issues with the tools >+ self.check_output("samba-tool dbcheck -s %s --cross-ncs --fix --yes" % (new_dc_config_file)) >+ except BlackboxProcessError as e: >+ self.assertTrue("Checked " in get_string(e.stdout)) >+ >+ self.check_output("samba-tool dbcheck -s %s --cross-ncs" % (new_dc_config_file)) >+ >+ # Compare the two directories >+ self.check_output("samba-tool ldapcmp ldap://%s ldb://%s %s --filter=%s" % >+ (self.dc1, new_dc_sam, self.cmdline_creds, >+ "msDs-masteredBy,msDS-NC-Replica-Locations,msDS-hasMasterNCs")) >+ >+ # Check all ForestDNS connections and backlinks >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % forestdns_dn) >+ self.assertEquals(len(res), 1) >+ res = samdb.search(base=forestdns_dn, >+ expression="(msds-masteredby=%s)" % server_ds_name) >+ self.assertEquals(len(res), 1) >+ res = samdb.search(controls=["search_options:1:2"], >+ expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" >+ % (server_ds_name, forestdns_dn)) >+ self.assertEquals(len(res), 1) >+ >+ # Check all DomainDNS connections and backlinks >+ res = samdb.search(base=server_ds_name, >+ expression="(msds-hasmasterncs=%s)" % domaindns_dn) >+ self.assertEquals(len(res), 1) >+ res = samdb.search(base=domaindns_dn, >+ expression="(msds-masteredby=%s)" % server_ds_name) >+ self.assertEquals(len(res), 1) >+ res = samdb.search(controls=["search_options:1:2"], >+ expression="(&(msds-nc-replica-locations=%s)(ncname=%s))" >+ % (server_ds_name, domaindns_dn)) >+ self.assertEquals(len(res), 1) >+ >+ # Demote the DC we created in the test >+ self.check_output("samba-tool domain demote --remove-other-dead-server=%s -H ldap://%s %s -s %s" >+ % (netbiosname, self.dc1, self.cmdline_creds, new_dc_config_file)) >-- >2.17.1 > > >From 02352ebbef6dd5669cb28369a3c7e7579c796384 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Mon, 29 Jul 2019 10:14:06 +1200 >Subject: [PATCH 017/376] WHATSNEW: Make it clearer how the AD database changes > will affect users > >The release notes currently just have a brief mention of a new LDB pack >format. They don't really cover how this change will actually affect AD >users when upgrading (or more specifically downgrading) with v4.11. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14057 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > WHATSNEW.txt | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index e91ad51c71b..c94b3541d7d 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -12,6 +12,32 @@ Samba 4.11 will be the next version of the Samba suite. > UPGRADING > ========= > >+AD Database compatibility >+------------------------- >+ >+Samba v4.11 has changed how the AD database is stored on disk. AD users should >+not really be affected by this change when upgrading to v4.11. However, AD >+users should be extremely careful if they need to downgrade from Samba v4.11 to >+an older release. >+ >+Samba v4.11 maintains database compatibility with older Samba releases. The >+database will automatically get rewritten in the new v4.11 format when you >+first start the upgraded samba executable. >+ >+However, when downgrading from v4.11 you will need to manually downgrade the AD >+database yourself. Note that you will need to do this step before you install >+the downgraded Samba packages. For more details, see: >+https://wiki.samba.org/index.php/Downgrading_an_Active_Directory_DC >+ >+When either upgrading or downgrading, users should also avoid making any >+database modifications between installing the new Samba packages and starting >+the samba executable. >+ >+Note that when moving between major Samba releases in general, we recommend >+that the AD DC is rejoined to the domain. Using this approach avoids the need >+to explicitly downgrade the database manually. For more details, see: >+https://wiki.samba.org/index.php/Upgrading_a_Samba_AD_DC >+ > SMB1 is disabled by default > --------------------------- > >-- >2.17.1 > > >From 6b4c51d0c94a34ccd310f4c0e470f043407659d6 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Mon, 29 Jul 2019 10:35:23 +1200 >Subject: [PATCH 018/376] WHATSNEW: Add link to 2012 Windows compatibility wiki > page > >There's now a lot more info on the wiki on Windows 2012 compatibility, >and how the schema is just a small part of overall compatibility. >Link to this wiki page from the WHATSNEW, so users can read more about >this. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14057 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >--- > WHATSNEW.txt | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index c94b3541d7d..3276d884f3a 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -142,6 +142,10 @@ Samba's replication code has also been improved to handle replication > with the 2012 schema (the core of this replication fix has also been > backported to 4.9.11 and will be in a 4.10.x release). > >+For more about how the AD schema relates to overall Windows compatibility, >+please read: >+https://wiki.samba.org/index.php/Windows_2012_Server_compatibility >+ > GnuTLS 3.2 required > ------------------- > >-- >2.17.1 > > >From 62e65124e9d720d5dd27d822e7a25df24ea9f81b Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 31 Jul 2019 14:17:02 +0200 >Subject: [PATCH 019/376] smbd: Fix use-after-free from exit_server_common() > >We need to keep the smbXsrv_connection structures around until all >pending requests have had their chance to clean up behind them. If you >look at srv_send_smb(), it's exactly prepared already to just drop >anything on the floor when the transport has been declared dead: > > if (!NT_STATUS_IS_OK(xconn->transport.status)) { > /* > * we're not supposed to do any io > */ > return true; > } > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=14064 > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Thu Aug 1 15:39:13 UTC 2019 on sn-devel-184 > >(cherry picked from commit c226dc6e8a18343031829c35552e557903593daf) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Aug 7 12:53:51 UTC 2019 on sn-devel-184 >--- > source3/smbd/server_exit.c | 22 +++++++++++++++------- > 1 file changed, 15 insertions(+), 7 deletions(-) > >diff --git a/source3/smbd/server_exit.c b/source3/smbd/server_exit.c >index 2378c0c15ca..b21501a7a23 100644 >--- a/source3/smbd/server_exit.c >+++ b/source3/smbd/server_exit.c >@@ -91,7 +91,6 @@ static void exit_server_common(enum server_exit_reason how, > { > struct smbXsrv_client *client = global_smbXsrv_client; > struct smbXsrv_connection *xconn = NULL; >- struct smbXsrv_connection *xconn_next = NULL; > struct smbd_server_connection *sconn = NULL; > struct messaging_context *msg_ctx = global_messaging_context(); > >@@ -110,10 +109,7 @@ static void exit_server_common(enum server_exit_reason how, > /* > * Here we typically have just one connection > */ >- for (; xconn != NULL; xconn = xconn_next) { >- xconn_next = xconn->next; >- DLIST_REMOVE(client->connections, xconn); >- >+ for (; xconn != NULL; xconn = xconn->next) { > /* > * This is typically the disconnect for the only > * (or with multi-channel last) connection of the client >@@ -128,8 +124,6 @@ static void exit_server_common(enum server_exit_reason how, > break; > } > } >- >- TALLOC_FREE(xconn); > DO_PROFILE_INC(disconnect); > } > >@@ -172,6 +166,20 @@ static void exit_server_common(enum server_exit_reason how, > > change_to_root_user(); > >+ if (client != NULL) { >+ struct smbXsrv_connection *xconn_next = NULL; >+ >+ for (xconn = client->connections; >+ xconn != NULL; >+ xconn = xconn_next) { >+ xconn_next = xconn->next; >+ DLIST_REMOVE(client->connections, xconn); >+ TALLOC_FREE(xconn); >+ } >+ } >+ >+ change_to_root_user(); >+ > /* 3 second timeout. */ > print_notify_send_messages(msg_ctx, 3); > >-- >2.17.1 > > >From 428ecb5f4e2bb399e90f50dcd56054062bbaf85a Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 13 Aug 2019 11:33:01 +0200 >Subject: [PATCH 020/376] WHATSNEW: Fix some minor formatting issues. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 35 +++++++++++++++++------------------ > 1 file changed, 17 insertions(+), 18 deletions(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index 3276d884f3a..6a0cc9d72fd 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -15,16 +15,16 @@ UPGRADING > AD Database compatibility > ------------------------- > >-Samba v4.11 has changed how the AD database is stored on disk. AD users should >-not really be affected by this change when upgrading to v4.11. However, AD >-users should be extremely careful if they need to downgrade from Samba v4.11 to >+Samba 4.11 has changed how the AD database is stored on disk. AD users should >+not really be affected by this change when upgrading to 4.11. However, AD >+users should be extremely careful if they need to downgrade from Samba 4.11 to > an older release. > >-Samba v4.11 maintains database compatibility with older Samba releases. The >-database will automatically get rewritten in the new v4.11 format when you >+Samba 4.11 maintains database compatibility with older Samba releases. The >+database will automatically get rewritten in the new 4.11 format when you > first start the upgraded samba executable. > >-However, when downgrading from v4.11 you will need to manually downgrade the AD >+However, when downgrading from 4.11 you will need to manually downgrade the AD > database yourself. Note that you will need to do this step before you install > the downgraded Samba packages. For more details, see: > https://wiki.samba.org/index.php/Downgrading_an_Active_Directory_DC >@@ -56,7 +56,7 @@ and LANMAN1 for client and server, as well as CORE and COREPLUS on > the client. > > Note that most commandline tools e.g. smbclient, smbcacls and others >-also support the --option argument to overwrite smb.conf options, >+also support the '--option' argument to overwrite smb.conf options, > e.g. --option='client min protocol=NT1' might be useful. > > As Microsoft no longer installs SMB1 support in recent releases >@@ -74,7 +74,7 @@ NEW FEATURES/CHANGES > Default samba process model > --------------------------- > >-The default for the --model argument passed to the samba executable has changed >+The default for the '--model' argument passed to the samba executable has changed > from 'standard' to 'prefork'. This means a difference in the number of samba > child processes that are created to handle client connections. The previous > default would create a separate process for every LDAP or NETLOGON client >@@ -102,26 +102,27 @@ where: > <command> is the name of the command makinmg the winbind request i.e. wbinfo > <pid> is the process id of the requesting process. > >-The version of the JSON Authentication messages has been changed to 1.2 from 1.1 >+The version of the JSON Authentication messages has been changed from 1.1 to >+1.2. > > LDAP referrals > -------------- > > The scheme of returned LDAP referrals now reflects the scheme of the original > request, i.e. referrals received via ldap are prefixed with "ldap://" >-and those over ldaps are prefixed with "ldaps://" >+and those over ldaps are prefixed with "ldaps://". > >-Previously all referrals were prefixed with "ldap://" >+Previously all referrals were prefixed with "ldap://". > > Bind9 logging > ------------- > >-It is now possible to log the duration of DNS operations performed by Bind9 >-This should aid future diagnosis of performance issues, and could be used to >+It is now possible to log the duration of DNS operations performed by Bind9. >+This should aid future diagnosis of performance issues and could be used to > monitor DNS performance. The logging is enabled by setting log level to >-"dns:10" in smb.conf >+"dns:10" in smb.conf. > >-The logs are currently Human readable text only, i.e. no JSON formatted output. >+The logs are currently human readable text only, i.e. no JSON formatted output. > > Log lines are of the form: > >@@ -210,7 +211,7 @@ multiple times into memory. > Setting lmdb map size > --------------------- > >-It is now possible to set the lmdb map size (The maximum permitted >+It is now possible to set the lmdb map size (the maximum permitted > size for the database). "samba-tool" now accepts the > "--backend-store-size" i.e. --backend-store-size=4Gb. If not > specified it defaults to 8Gb. >@@ -302,14 +303,12 @@ Samba still supported a Python WSGI web server (which could still be turned on > from the 'server services' smb.conf parameter). This service was unused and has > now been removed from Samba. > >- > samba-tool join subdomain > ------------------------- > > The subdomain role has been removed from the join command. This option did > not work and has no tests. > >- > Python2 support > --------------- > >-- >2.17.1 > > >From 8dfa63d9f7236a534fb454e50e6dff41d07ae89c Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Thu, 1 Aug 2019 21:08:52 +0300 >Subject: [PATCH 021/376] torture/rpc/lsa: allow testing different lookup > levels > >Convert torture/rpc/lsa LookupNames/LookupSids code to allow testing >different LSA_LOOKUP_NAMES_* levels. Keep existing level 1 >(LSA_LOOKUP_NAMES_ALL) for the current set of tests. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14091 > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >(cherry picked from commit 317bc6a7342edfa2c503f5932142bf5883485cc9) >--- > source4/torture/rpc/lsa.c | 118 ++++++++++++++++++--------------- > source4/torture/rpc/schannel.c | 2 +- > 2 files changed, 67 insertions(+), 53 deletions(-) > >diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c >index 5b16ed9a014..fdbfcbffc16 100644 >--- a/source4/torture/rpc/lsa.c >+++ b/source4/torture/rpc/lsa.c >@@ -281,6 +281,7 @@ static bool test_OpenPolicy2_fail(struct dcerpc_binding_handle *b, > static bool test_LookupNames(struct dcerpc_binding_handle *b, > struct torture_context *tctx, > struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level, > struct lsa_TransNameArray *tnames) > { > struct lsa_LookupNames r; >@@ -313,7 +314,7 @@ static bool test_LookupNames(struct dcerpc_binding_handle *b, > r.in.handle = handle; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.out.count = &count; > r.out.sids = &sids; >@@ -369,7 +370,8 @@ static bool test_LookupNames(struct dcerpc_binding_handle *b, > > static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >- struct policy_handle *handle) >+ struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level) > { > struct lsa_LookupNames r; > struct lsa_TransSidArray sids; >@@ -388,7 +390,7 @@ static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b, > r.in.num_names = 1; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.out.count = &count; > r.out.sids = &sids; >@@ -409,7 +411,8 @@ static bool test_LookupNames_bogus(struct dcerpc_binding_handle *b, > > static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >- struct policy_handle *handle) >+ struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level) > { > struct lsa_LookupNames r; > struct lsa_TransSidArray sids; >@@ -428,7 +431,7 @@ static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b, > r.in.num_names = 1; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.out.count = &count; > r.out.sids = &sids; >@@ -453,7 +456,8 @@ static bool test_LookupNames_NULL(struct dcerpc_binding_handle *b, > > static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >- struct policy_handle *handle) >+ struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level) > { > struct lsa_TranslatedName name; > struct lsa_TransNameArray tnames; >@@ -465,45 +469,46 @@ static bool test_LookupNames_wellknown(struct dcerpc_binding_handle *b, > tnames.count = 1; > name.name.string = "NT AUTHORITY\\SYSTEM"; > name.sid_type = SID_NAME_WKN_GRP; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "NT AUTHORITY\\ANONYMOUS LOGON"; > name.sid_type = SID_NAME_WKN_GRP; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "NT AUTHORITY\\Authenticated Users"; > name.sid_type = SID_NAME_WKN_GRP; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > #if 0 > name.name.string = "NT AUTHORITY"; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "NT AUTHORITY\\"; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > #endif > > name.name.string = "BUILTIN\\"; > name.sid_type = SID_NAME_DOMAIN; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "BUILTIN\\Administrators"; > name.sid_type = SID_NAME_ALIAS; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "SYSTEM"; > name.sid_type = SID_NAME_WKN_GRP; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > > name.name.string = "Everyone"; > name.sid_type = SID_NAME_WKN_GRP; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, level, &tnames); > return ret; > } > > static bool test_LookupNames2(struct dcerpc_binding_handle *b, > struct torture_context *tctx, > struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level, > struct lsa_TransNameArray2 *tnames, > bool check_result) > { >@@ -536,7 +541,7 @@ static bool test_LookupNames2(struct dcerpc_binding_handle *b, > r.in.handle = handle; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -565,6 +570,7 @@ static bool test_LookupNames2(struct dcerpc_binding_handle *b, > static bool test_LookupNames3(struct dcerpc_binding_handle *b, > struct torture_context *tctx, > struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level, > struct lsa_TransNameArray2 *tnames, > bool check_result) > { >@@ -596,7 +602,7 @@ static bool test_LookupNames3(struct dcerpc_binding_handle *b, > r.in.handle = handle; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -624,6 +630,7 @@ static bool test_LookupNames3(struct dcerpc_binding_handle *b, > > static bool test_LookupNames4(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >+ enum lsa_LookupNamesLevel level, > struct lsa_TransNameArray2 *tnames, > bool check_result) > { >@@ -655,7 +662,7 @@ static bool test_LookupNames4(struct dcerpc_binding_handle *b, > r.in.num_names = tnames->count; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -693,7 +700,8 @@ static bool test_LookupNames4(struct dcerpc_binding_handle *b, > } > > static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b, >- struct torture_context *tctx) >+ struct torture_context *tctx, >+ enum lsa_LookupNamesLevel level) > { > struct lsa_LookupNames4 r; > struct lsa_TransSidArray3 sids; >@@ -712,7 +720,7 @@ static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b, > r.in.num_names = count; > r.in.names = names; > r.in.sids = &sids; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -760,6 +768,7 @@ static bool test_LookupNames4_fail(struct dcerpc_binding_handle *b, > static bool test_LookupSids(struct dcerpc_binding_handle *b, > struct torture_context *tctx, > struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level, > struct lsa_SidArray *sids) > { > struct lsa_LookupSids r; >@@ -775,7 +784,7 @@ static bool test_LookupSids(struct dcerpc_binding_handle *b, > r.in.handle = handle; > r.in.sids = sids; > r.in.names = &names; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.out.count = &count; > r.out.names = &names; >@@ -790,7 +799,7 @@ static bool test_LookupSids(struct dcerpc_binding_handle *b, > > torture_comment(tctx, "\n"); > >- if (!test_LookupNames(b, tctx, handle, &names)) { >+ if (!test_LookupNames(b, tctx, handle, level, &names)) { > return false; > } > >@@ -801,6 +810,7 @@ static bool test_LookupSids(struct dcerpc_binding_handle *b, > static bool test_LookupSids2(struct dcerpc_binding_handle *b, > struct torture_context *tctx, > struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level, > struct lsa_SidArray *sids) > { > struct lsa_LookupSids2 r; >@@ -816,7 +826,7 @@ static bool test_LookupSids2(struct dcerpc_binding_handle *b, > r.in.handle = handle; > r.in.sids = sids; > r.in.names = &names; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -835,11 +845,11 @@ static bool test_LookupSids2(struct dcerpc_binding_handle *b, > > torture_comment(tctx, "\n"); > >- if (!test_LookupNames2(b, tctx, handle, &names, false)) { >+ if (!test_LookupNames2(b, tctx, handle, level, &names, false)) { > return false; > } > >- if (!test_LookupNames3(b, tctx, handle, &names, false)) { >+ if (!test_LookupNames3(b, tctx, handle, level, &names, false)) { > return false; > } > >@@ -848,6 +858,7 @@ static bool test_LookupSids2(struct dcerpc_binding_handle *b, > > static bool test_LookupSids3(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >+ enum lsa_LookupNamesLevel level, > struct lsa_SidArray *sids) > { > struct lsa_LookupSids3 r; >@@ -862,7 +873,7 @@ static bool test_LookupSids3(struct dcerpc_binding_handle *b, > > r.in.sids = sids; > r.in.names = &names; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -891,7 +902,7 @@ static bool test_LookupSids3(struct dcerpc_binding_handle *b, > > torture_comment(tctx, "\n"); > >- if (!test_LookupNames4(b, tctx, &names, true)) { >+ if (!test_LookupNames4(b, tctx, level, &names, true)) { > return false; > } > >@@ -900,6 +911,7 @@ static bool test_LookupSids3(struct dcerpc_binding_handle *b, > > static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >+ enum lsa_LookupNamesLevel level, > struct lsa_SidArray *sids) > { > struct lsa_LookupSids3 r; >@@ -915,7 +927,7 @@ static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b, > > r.in.sids = sids; > r.in.names = &names; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &count; > r.in.lookup_options = 0; > r.in.client_revision = 0; >@@ -959,7 +971,8 @@ static bool test_LookupSids3_fail(struct dcerpc_binding_handle *b, > > bool test_many_LookupSids(struct dcerpc_pipe *p, > struct torture_context *tctx, >- struct policy_handle *handle) >+ struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level) > { > uint32_t count; > struct lsa_SidArray sids; >@@ -990,7 +1003,7 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, > r.in.handle = handle; > r.in.sids = &sids; > r.in.names = &names; >- r.in.level = 1; >+ r.in.level = level; > r.in.count = &names.count; > r.out.count = &count; > r.out.names = &names; >@@ -1006,16 +1019,16 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, > > torture_comment(tctx, "\n"); > >- if (!test_LookupNames(b, tctx, handle, &names)) { >+ if (!test_LookupNames(b, tctx, handle, level, &names)) { > return false; > } > } > > if (transport == NCACN_NP) { >- if (!test_LookupSids3_fail(b, tctx, &sids)) { >+ if (!test_LookupSids3_fail(b, tctx, level, &sids)) { > return false; > } >- if (!test_LookupNames4_fail(b, tctx)) { >+ if (!test_LookupNames4_fail(b, tctx, level)) { > return false; > } > } else if (transport == NCACN_IP_TCP) { >@@ -1031,10 +1044,10 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, > > if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL && > auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) { >- if (!test_LookupSids3(b, tctx, &sids)) { >+ if (!test_LookupSids3(b, tctx, level, &sids)) { > return false; > } >- if (!test_LookupNames4(b, tctx, &names, true)) { >+ if (!test_LookupNames4(b, tctx, level, &names, true)) { > return false; > } > } else { >@@ -1042,10 +1055,10 @@ bool test_many_LookupSids(struct dcerpc_pipe *p, > * If we don't have a secure channel these tests must > * fail with ACCESS_DENIED. > */ >- if (!test_LookupSids3_fail(b, tctx, &sids)) { >+ if (!test_LookupSids3_fail(b, tctx, level, &sids)) { > return false; > } >- if (!test_LookupNames4_fail(b, tctx)) { >+ if (!test_LookupNames4_fail(b, tctx, level)) { > return false; > } > } >@@ -1077,7 +1090,8 @@ static void lookupsids_cb(struct tevent_req *subreq) > > static bool test_LookupSids_async(struct dcerpc_binding_handle *b, > struct torture_context *tctx, >- struct policy_handle *handle) >+ struct policy_handle *handle, >+ enum lsa_LookupNamesLevel level) > { > struct lsa_SidArray sids; > struct lsa_SidPtr sidptr; >@@ -1112,7 +1126,7 @@ static bool test_LookupSids_async(struct dcerpc_binding_handle *b, > r[i].in.handle = handle; > r[i].in.sids = &sids; > r[i].in.names = &names[i]; >- r[i].in.level = 1; >+ r[i].in.level = level; > r[i].in.count = &names[i].count; > r[i].out.count = &count[i]; > r[i].out.names = &names[i]; >@@ -1923,11 +1937,11 @@ static bool test_EnumAccounts(struct dcerpc_binding_handle *b, > torture_assert_ntstatus_ok(tctx, r.out.result, > "EnumAccounts failed"); > >- if (!test_LookupSids(b, tctx, handle, &sids1)) { >+ if (!test_LookupSids(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) { > return false; > } > >- if (!test_LookupSids2(b, tctx, handle, &sids1)) { >+ if (!test_LookupSids2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &sids1)) { > return false; > } > >@@ -4836,7 +4850,7 @@ static bool test_QueryInfoPolicyCalls( bool version2, > tnames.names[12].sid_type = SID_NAME_USER; > tnames.names[13].name.string = talloc_asprintf(tctx, TEST_MACHINENAME "$@%s", info->dns.dns_domain.string); > tnames.names[13].sid_type = SID_NAME_USER; >- ret &= test_LookupNames(b, tctx, handle, &tnames); >+ ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames); > > } > } >@@ -5002,7 +5016,7 @@ bool torture_rpc_lsa(struct torture_context *tctx) > ret = false; > } > >- if (!test_many_LookupSids(p, tctx, handle)) { >+ if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >@@ -5023,7 +5037,7 @@ bool torture_rpc_lsa(struct torture_context *tctx) > ret = false; > } > >- if (!test_LookupSids_async(b, tctx, handle)) { >+ if (!test_LookupSids_async(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >@@ -5047,7 +5061,7 @@ bool torture_rpc_lsa(struct torture_context *tctx) > ret = false; > } > >- if (!test_many_LookupSids(p, tctx, handle)) { >+ if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >@@ -5058,7 +5072,7 @@ bool torture_rpc_lsa(struct torture_context *tctx) > torture_leave_domain(tctx, join); > > } else { >- if (!test_many_LookupSids(p, tctx, handle)) { >+ if (!test_many_LookupSids(p, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > } >@@ -5133,7 +5147,7 @@ static bool testcase_LookupNames(struct torture_context *tctx, > tnames.names[0].name.string = "BUILTIN"; > tnames.names[0].sid_type = SID_NAME_DOMAIN; > >- if (!test_LookupNames(b, tctx, handle, &tnames)) { >+ if (!test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames)) { > ret = false; > } > >@@ -5143,23 +5157,23 @@ static bool testcase_LookupNames(struct torture_context *tctx, > tnames2.names[0].name.string = "BUILTIN"; > tnames2.names[0].sid_type = SID_NAME_DOMAIN; > >- if (!test_LookupNames2(b, tctx, handle, &tnames2, true)) { >+ if (!test_LookupNames2(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) { > ret = false; > } > >- if (!test_LookupNames3(b, tctx, handle, &tnames2, true)) { >+ if (!test_LookupNames3(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames2, true)) { > ret = false; > } > >- if (!test_LookupNames_wellknown(b, tctx, handle)) { >+ if (!test_LookupNames_wellknown(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >- if (!test_LookupNames_NULL(b, tctx, handle)) { >+ if (!test_LookupNames_NULL(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >- if (!test_LookupNames_bogus(b, tctx, handle)) { >+ if (!test_LookupNames_bogus(b, tctx, handle, LSA_LOOKUP_NAMES_ALL)) { > ret = false; > } > >diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c >index 5b40af216a5..fff0b1aacbd 100644 >--- a/source4/torture/rpc/schannel.c >+++ b/source4/torture/rpc/schannel.c >@@ -470,7 +470,7 @@ static bool test_schannel(struct torture_context *tctx, > "failed to connect lsarpc with schannel"); > > torture_assert(tctx, >- test_many_LookupSids(p_lsa, tctx, NULL), >+ test_many_LookupSids(p_lsa, tctx, NULL, LSA_LOOKUP_NAMES_ALL), > "LsaLookupSids3 failed!\n"); > > status = dcerpc_binding_set_transport(b, transport); >-- >2.17.1 > > >From 60d222327343599d13643ee54e041cd65373a7eb Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Thu, 1 Aug 2019 15:48:58 +0300 >Subject: [PATCH 022/376] lookup_name: allow own domain lookup when flags == 0 > >In 2007, we've added support for multiple lookup levels for LSA >LookupNames family of calls. However, forest-wide lookups, as described >in MS-LSAT 2.2.16, never worked because flags passed to lookup_name() >were always set to zero, expecting at least default lookup on a DC to >apply. lookup_name() was instead treating zero flags as 'skip all >checks'. > >Allow at least own domain lookup in case domain name is the same. >This should allow FreeIPA DC to respond to LSA LookupNames3 calls from a >trusted AD DC side. > >For the reference, below is a request Windows Server 2016 domain >controller sends to FreeIPA domain controller when attempting to look up >a user from a trusted forest root domain that attemps to login to the >domain controller. Notice the level in the lsa_LookupNames3 call and >resulting flags in lookup_name(). > >[2019/08/03 07:14:24.156065, 1, pid=23639, effective(967001000, 967001000), real(967001000, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug) > lsa_LookupNames3: struct lsa_LookupNames3 > in: struct lsa_LookupNames3 > handle : * > handle: struct policy_handle > handle_type : 0x00000000 (0) > uuid : 0000004c-0000-0000-455d-3018575c0000 > num_names : 0x00000001 (1) > names: ARRAY(1) > names: struct lsa_String > length : 0x000a (10) > size : 0x000c (12) > string : * > string : 'XS\ab' > sids : * > sids: struct lsa_TransSidArray3 > count : 0x00000000 (0) > sids : NULL > level : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6) > count : * > count : 0x00000000 (0) > lookup_options : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0) > client_revision : LSA_CLIENT_REVISION_2 (2) >[2019/08/03 07:14:24.156189, 6, pid=23639, effective(967001000, 967001000), real(967001000, 0), class=rpc_srv] ../../source3/rpc_server/rpc_handles.c:339(find_policy_by_hnd_internal) > Found policy hnd[0] [0000] 00 00 00 00 4C 00 00 00 00 00 00 00 45 5D 30 18 ....L... ....E]0. > [0010] 57 5C 00 00 W\.. >[2019/08/03 07:14:24.156228, 4, pid=23639, effective(967001000, 967001000), real(967001000, 0)] ../../source3/smbd/sec_ctx.c:215(push_sec_ctx) > push_sec_ctx(967001000, 967001000) : sec_ctx_stack_ndx = 2 >[2019/08/03 07:14:24.156246, 4, pid=23639, effective(967001000, 967001000), real(967001000, 0)] ../../source3/smbd/uid.c:552(push_conn_ctx) > push_conn_ctx(0) : conn_ctx_stack_ndx = 0 >[2019/08/03 07:14:24.156259, 4, pid=23639, effective(967001000, 967001000), real(967001000, 0)] ../../source3/smbd/sec_ctx.c:319(set_sec_ctx_internal) > setting sec ctx (0, 0) - sec_ctx_stack_ndx = 2 >[2019/08/03 07:14:24.156273, 5, pid=23639, effective(967001000, 967001000), real(967001000, 0)] ../../libcli/security/security_token.c:53(security_token_debug) > Security token: (NULL) >[2019/08/03 07:14:24.156285, 5, pid=23639, effective(967001000, 967001000), real(967001000, 0)] ../../source3/auth/token_util.c:865(debug_unix_user_token) > UNIX token of user 0 > Primary group is 0 and contains 0 supplementary groups >[2019/08/03 07:14:24.156311, 5, pid=23639, effective(0, 0), real(0, 0), class=rpc_srv] ../../source3/rpc_server/lsa/srv_lsa_nt.c:244(lookup_lsa_sids) > lookup_lsa_sids: looking up name XS\ab >[2019/08/03 07:14:24.156327, 10, pid=23639, effective(0, 0), real(0, 0)] ../../source3/passdb/lookup_sid.c:112(lookup_name) > lookup_name: XS\ab => domain=[XS], name=[ab] >[2019/08/03 07:14:24.156340, 10, pid=23639, effective(0, 0), real(0, 0)] ../../source3/passdb/lookup_sid.c:114(lookup_name) > lookup_name: flags = 0x00 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14091 > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >(cherry picked from commit 685bb03de6ab733590831d1df4f5fd60d2ac427d) >--- > source3/passdb/lookup_sid.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c >index 6ab72e57838..c31a9e48739 100644 >--- a/source3/passdb/lookup_sid.c >+++ b/source3/passdb/lookup_sid.c >@@ -113,7 +113,7 @@ bool lookup_name(TALLOC_CTX *mem_ctx, > full_name, domain, name)); > DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags)); > >- if ((flags & LOOKUP_NAME_DOMAIN) && >+ if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) && > strequal(domain, get_global_sam_name())) > { > >-- >2.17.1 > > >From 38876ad4ef46fc3cf6a12329236918a87c2e2c65 Mon Sep 17 00:00:00 2001 >From: Alexander Bokovoy <ab@samba.org> >Date: Sat, 10 Aug 2019 11:53:12 +0300 >Subject: [PATCH 023/376] smbtorture: extend rpc.lsa to lookup machine over > forest-wide LookupNames > >Add a simple test to resolve DOMAIN\MACHINE$ via LSA LookupNames3 >using LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 level. This level would pass >zero lookup flags to lookup_name(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14091 > >Signed-off-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Alexander Bokovoy <ab@samba.org> >Autobuild-Date(master): Wed Aug 14 13:07:42 UTC 2019 on sn-devel-184 > >(cherry picked from commit 4d276a93fc624dc04d880f5b4157f272d3555be6) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Mon Aug 19 12:36:22 UTC 2019 on sn-devel-184 >--- > source4/torture/rpc/lsa.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c >index fdbfcbffc16..0ce113feb5d 100644 >--- a/source4/torture/rpc/lsa.c >+++ b/source4/torture/rpc/lsa.c >@@ -4819,7 +4819,7 @@ static bool test_QueryInfoPolicyCalls( bool version2, > || i == LSA_POLICY_INFO_DNS_INT)) { > /* Let's look up some of these names */ > >- struct lsa_TransNameArray tnames; >+ struct lsa_TransNameArray tnames, dnames; > tnames.count = 14; > tnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, tnames.count); > tnames.names[0].name.string = info->dns.name.string; >@@ -4852,6 +4852,12 @@ static bool test_QueryInfoPolicyCalls( bool version2, > tnames.names[13].sid_type = SID_NAME_USER; > ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_ALL, &tnames); > >+ /* Try to use in-forest search for the test machine */ >+ dnames.count = 1; >+ dnames.names = talloc_zero_array(tctx, struct lsa_TranslatedName, dnames.count); >+ dnames.names[0].name.string = talloc_asprintf(tctx, "%s\\"TEST_MACHINENAME "$", info->dns.name.string); >+ dnames.names[0].sid_type = SID_NAME_USER; >+ ret &= test_LookupNames(b, tctx, handle, LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2, &dnames); > } > } > >-- >2.17.1 > > >From fab20658b9a4d04e2eab89d95b6eb7e04187424d Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 4 Aug 2019 12:10:03 +0200 >Subject: [PATCH 024/376] tdb: Rename tdb_oob() to tdb_notrans_oob() > >tdb_oob() will become a public function encapsulating the pointer >dereferences. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 885ba572efaac6c20388b8e119315c837e8f5236) >--- > lib/tdb/common/io.c | 6 +++--- > lib/tdb/test/run-3G-file.c | 2 +- > 2 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c >index df460176159..06492b1407d 100644 >--- a/lib/tdb/common/io.c >+++ b/lib/tdb/common/io.c >@@ -136,8 +136,8 @@ static int tdb_fstat(struct tdb_context *tdb, struct stat *buf) > see if the database has been expanded by someone else and expand > if necessary > */ >-static int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, >- int probe) >+static int tdb_notrans_oob( >+ struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) > { > struct stat st; > if (len + off < len) { >@@ -782,7 +782,7 @@ static const struct tdb_methods io_methods = { > tdb_read, > tdb_write, > tdb_next_hash_chain, >- tdb_oob, >+ tdb_notrans_oob, > tdb_expand_file, > }; > >diff --git a/lib/tdb/test/run-3G-file.c b/lib/tdb/test/run-3G-file.c >index 748c972284a..79e291b294e 100644 >--- a/lib/tdb/test/run-3G-file.c >+++ b/lib/tdb/test/run-3G-file.c >@@ -48,7 +48,7 @@ static const struct tdb_methods large_io_methods = { > tdb_read, > tdb_write, > tdb_next_hash_chain, >- tdb_oob, >+ tdb_notrans_oob, > tdb_expand_file_sparse > }; > >-- >2.17.1 > > >From 6312223d6e609d629dfc7914d62bf80ced584c6b Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 4 Aug 2019 12:15:14 +0200 >Subject: [PATCH 025/376] tdb: Introduce tdb_oob() > >Initially just encapsulate the pointer dereferences > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 5a388453e0cb038fa3ed5fb46f972470f7793566) >--- > lib/tdb/common/check.c | 6 +++--- > lib/tdb/common/freelist.c | 2 +- > lib/tdb/common/io.c | 22 ++++++++++++++-------- > lib/tdb/common/open.c | 6 +++--- > lib/tdb/common/rescue.c | 4 ++-- > lib/tdb/common/tdb_private.h | 1 + > lib/tdb/common/transaction.c | 2 +- > lib/tdb/common/traverse.c | 3 +-- > 8 files changed, 26 insertions(+), 20 deletions(-) > >diff --git a/lib/tdb/common/check.c b/lib/tdb/common/check.c >index 3a5c8b8ba94..d7741f6b2f9 100644 >--- a/lib/tdb/common/check.c >+++ b/lib/tdb/common/check.c >@@ -94,7 +94,7 @@ static bool tdb_check_record(struct tdb_context *tdb, > off, rec->next)); > goto corrupt; > } >- if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0)) >+ if (tdb_oob(tdb, rec->next, sizeof(*rec), 0)) > goto corrupt; > > /* Check rec_len: similar to rec->next, implies next record. */ >@@ -112,7 +112,7 @@ static bool tdb_check_record(struct tdb_context *tdb, > goto corrupt; > } > /* OOB allows "right at the end" access, so this works for last rec. */ >- if (tdb->methods->tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) >+ if (tdb_oob(tdb, off, sizeof(*rec)+rec->rec_len, 0)) > goto corrupt; > > /* Check tailer. */ >@@ -362,7 +362,7 @@ _PUBLIC_ int tdb_check(struct tdb_context *tdb, > } > > /* Make sure we know true size of the underlying file. */ >- tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); >+ tdb_oob(tdb, tdb->map_size, 1, 1); > > /* Header must be OK: also gets us the recovery ptr, if any. */ > if (!tdb_check_header(tdb, &recovery_start)) >diff --git a/lib/tdb/common/freelist.c b/lib/tdb/common/freelist.c >index 37a4c168533..046c747cf9b 100644 >--- a/lib/tdb/common/freelist.c >+++ b/lib/tdb/common/freelist.c >@@ -50,7 +50,7 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record > rec->magic, off)); > return -1; > } >- if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) >+ if (tdb_oob(tdb, rec->next, sizeof(*rec), 0) != 0) > return -1; > return 0; > } >diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c >index 06492b1407d..f3ea7bf9856 100644 >--- a/lib/tdb/common/io.c >+++ b/lib/tdb/common/io.c >@@ -216,7 +216,7 @@ static int tdb_write(struct tdb_context *tdb, tdb_off_t off, > return -1; > } > >- if (tdb->methods->tdb_oob(tdb, off, len, 0) != 0) >+ if (tdb_oob(tdb, off, len, 0) != 0) > return -1; > > if (tdb->map_ptr) { >@@ -271,7 +271,7 @@ void *tdb_convert(void *buf, uint32_t size) > static int tdb_read(struct tdb_context *tdb, tdb_off_t off, void *buf, > tdb_len_t len, int cv) > { >- if (tdb->methods->tdb_oob(tdb, off, len, 0) != 0) { >+ if (tdb_oob(tdb, off, len, 0) != 0) { > return -1; > } > >@@ -596,7 +596,7 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) > } > > /* must know about any previous expansions by another process */ >- tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); >+ tdb_oob(tdb, tdb->map_size, 1, 1); > > /* > * Note: that we don't care about tdb->hdr_ofs != 0 here >@@ -662,6 +662,12 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) > return -1; > } > >+int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) >+{ >+ int ret = tdb->methods->tdb_oob(tdb, off, len, probe); >+ return ret; >+} >+ > /* read/write a tdb_off_t */ > int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d) > { >@@ -714,7 +720,7 @@ int tdb_parse_data(struct tdb_context *tdb, TDB_DATA key, > * Optimize by avoiding the malloc/memcpy/free, point the > * parser directly at the mmap area. > */ >- if (tdb->methods->tdb_oob(tdb, offset, len, 0) != 0) { >+ if (tdb_oob(tdb, offset, len, 0) != 0) { > return -1; > } > data.dptr = offset + (unsigned char *)tdb->map_ptr; >@@ -756,20 +762,20 @@ int tdb_rec_read(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *r > return -1; > } > >- ret = tdb->methods->tdb_oob(tdb, offset, rec->key_len, 1); >+ ret = tdb_oob(tdb, offset, rec->key_len, 1); > if (ret == -1) { > return -1; > } >- ret = tdb->methods->tdb_oob(tdb, offset, rec->data_len, 1); >+ ret = tdb_oob(tdb, offset, rec->data_len, 1); > if (ret == -1) { > return -1; > } >- ret = tdb->methods->tdb_oob(tdb, offset, rec->rec_len, 1); >+ ret = tdb_oob(tdb, offset, rec->rec_len, 1); > if (ret == -1) { > return -1; > } > >- return tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 0); >+ return tdb_oob(tdb, rec->next, sizeof(*rec), 0); > } > > int tdb_rec_write(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec) >diff --git a/lib/tdb/common/open.c b/lib/tdb/common/open.c >index dd5783ef8bc..f7f65b0e237 100644 >--- a/lib/tdb/common/open.c >+++ b/lib/tdb/common/open.c >@@ -655,7 +655,7 @@ _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int td > * As this skips tdb->hdr_ofs. > */ > tdb->map_size = 0; >- ret = tdb->methods->tdb_oob(tdb, 0, 1, 0); >+ ret = tdb_oob(tdb, 0, 1, 0); > if (ret == -1) { > errno = EIO; > goto fail; >@@ -677,7 +677,7 @@ _PUBLIC_ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int td > goto fail; > } > >- ret = tdb->methods->tdb_oob(tdb, FREELIST_TOP, 4*tdb->hash_size, 1); >+ ret = tdb_oob(tdb, FREELIST_TOP, 4*tdb->hash_size, 1); > if (ret == -1) { > TDB_LOG((tdb, TDB_DEBUG_FATAL, "tdb_open_ex: " > "hash size %"PRIu32" does not fit\n", tdb->hash_size)); >@@ -895,7 +895,7 @@ static int tdb_reopen_internal(struct tdb_context *tdb, bool active_lock) > * As this skips tdb->hdr_ofs. > */ > tdb->map_size = 0; >- if (tdb->methods->tdb_oob(tdb, 0, 1, 0) != 0) { >+ if (tdb_oob(tdb, 0, 1, 0) != 0) { > goto fail; > } > #endif /* fake pread or pwrite */ >diff --git a/lib/tdb/common/rescue.c b/lib/tdb/common/rescue.c >index e608db41dea..7a85ebc9311 100644 >--- a/lib/tdb/common/rescue.c >+++ b/lib/tdb/common/rescue.c >@@ -60,7 +60,7 @@ static bool looks_like_valid_record(struct tdb_context *tdb, > if (rec->next > 0 && rec->next < TDB_DATA_START(tdb->hash_size)) > return false; > >- if (tdb->methods->tdb_oob(tdb, rec->next, sizeof(*rec), 1)) >+ if (tdb_oob(tdb, rec->next, sizeof(*rec), 1)) > return false; > > key->dsize = rec->key_len; >@@ -228,7 +228,7 @@ _PUBLIC_ int tdb_rescue(struct tdb_context *tdb, > } > > /* Make sure we know true size of the underlying file. */ >- tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); >+ tdb_oob(tdb, tdb->map_size, 1, 1); > > /* Suppress logging, since we anticipate errors. */ > tdb->log.log_fn = logging_suppressed; >diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h >index 42aaac62f59..2bed8200f94 100644 >--- a/lib/tdb/common/tdb_private.h >+++ b/lib/tdb/common/tdb_private.h >@@ -304,6 +304,7 @@ void *tdb_convert(void *buf, uint32_t size); > int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); > tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, > struct tdb_record *rec); >+int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); > int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); > int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); > int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); >diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c >index e9b0b26ea59..b22624820d7 100644 >--- a/lib/tdb/common/transaction.c >+++ b/lib/tdb/common/transaction.c >@@ -524,7 +524,7 @@ static int _tdb_transaction_start(struct tdb_context *tdb, > > /* make sure we know about any file expansions already done by > anyone else */ >- tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1); >+ tdb_oob(tdb, tdb->map_size, 1, 1); > tdb->transaction->old_map_size = tdb->map_size; > > /* finally hook the io methods, replacing them with >diff --git a/lib/tdb/common/traverse.c b/lib/tdb/common/traverse.c >index 54a69dc8d03..d69e7dff285 100644 >--- a/lib/tdb/common/traverse.c >+++ b/lib/tdb/common/traverse.c >@@ -453,8 +453,7 @@ _PUBLIC_ int tdb_traverse_chain(struct tdb_context *tdb, > > if ((tdb->transaction == NULL) && > (tdb->map_ptr != NULL)) { >- ret = tdb->methods->tdb_oob( >- tdb, key_ofs, full_len, 0); >+ ret = tdb_oob(tdb, key_ofs, full_len, 0); > if (ret == -1) { > goto fail; > } >-- >2.17.1 > > >From 3325a4d4146d5793b1ae6a7b7a502c52a489ac59 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 4 Aug 2019 12:18:19 +0200 >Subject: [PATCH 026/376] tdb: Speed up tdb_oob() > >This is common between both implementations of tdb_oob(). It's >faster if we don't have to dereference function pointers. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 897bffa8166f643eb9063a848bb0c02455663317) >--- > lib/tdb/common/io.c | 13 ++++++++++++- > lib/tdb/common/transaction.c | 5 +++++ > 2 files changed, 17 insertions(+), 1 deletion(-) > >diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c >index f3ea7bf9856..28e808143a2 100644 >--- a/lib/tdb/common/io.c >+++ b/lib/tdb/common/io.c >@@ -150,6 +150,11 @@ static int tdb_notrans_oob( > return -1; > } > >+ /* >+ * This duplicates functionality from tdb_oob(). Don't remove: >+ * we still have direct callers of tdb->methods->tdb_oob() >+ * inside transaction.c. >+ */ > if (off + len <= tdb->map_size) > return 0; > if (tdb->flags & TDB_INTERNAL) { >@@ -664,7 +669,13 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) > > int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) > { >- int ret = tdb->methods->tdb_oob(tdb, off, len, probe); >+ int ret; >+ >+ if (likely((off + len >= off) && (off + len <= tdb->map_size))) { >+ return 0; >+ } >+ >+ ret = tdb->methods->tdb_oob(tdb, off, len, probe); > return ret; > } > >diff --git a/lib/tdb/common/transaction.c b/lib/tdb/common/transaction.c >index b22624820d7..4f8d1f8cdcc 100644 >--- a/lib/tdb/common/transaction.c >+++ b/lib/tdb/common/transaction.c >@@ -378,6 +378,11 @@ static void transaction_next_hash_chain(struct tdb_context *tdb, uint32_t *chain > static int transaction_oob(struct tdb_context *tdb, tdb_off_t off, > tdb_len_t len, int probe) > { >+ /* >+ * This duplicates functionality from tdb_oob(). Don't remove: >+ * we still have direct callers of tdb->methods->tdb_oob() >+ * inside transaction.c. >+ */ > if (off + len >= off && off + len <= tdb->map_size) { > return 0; > } >-- >2.17.1 > > >From afd6b77bb849bdcfa30513626c61a7aade7d88e2 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 4 Aug 2019 18:26:05 +0200 >Subject: [PATCH 027/376] tdb: Inline the common part of tdb_oob > >When you set > >in tdbtorture.c to make it more similar to locking.tdb use, > >bin/tdbtorture -m -n 1 -l 100000 -s > >becomes twice as fast. This is a pretty extreme case, but all other >tests that I did improve significantly as well. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit f5735e2c666a5a494131c1d25f7ba5c7fbeae923) >--- > lib/tdb/common/io.c | 10 ++-------- > lib/tdb/common/tdb_private.h | 14 +++++++++++++- > 2 files changed, 15 insertions(+), 9 deletions(-) > >diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c >index 28e808143a2..0de0dabd827 100644 >--- a/lib/tdb/common/io.c >+++ b/lib/tdb/common/io.c >@@ -667,15 +667,9 @@ int tdb_expand(struct tdb_context *tdb, tdb_off_t size) > return -1; > } > >-int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) >+int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) > { >- int ret; >- >- if (likely((off + len >= off) && (off + len <= tdb->map_size))) { >- return 0; >- } >- >- ret = tdb->methods->tdb_oob(tdb, off, len, probe); >+ int ret = tdb->methods->tdb_oob(tdb, off, len, probe); > return ret; > } > >diff --git a/lib/tdb/common/tdb_private.h b/lib/tdb/common/tdb_private.h >index 2bed8200f94..29790434211 100644 >--- a/lib/tdb/common/tdb_private.h >+++ b/lib/tdb/common/tdb_private.h >@@ -304,7 +304,19 @@ void *tdb_convert(void *buf, uint32_t size); > int tdb_free(struct tdb_context *tdb, tdb_off_t offset, struct tdb_record *rec); > tdb_off_t tdb_allocate(struct tdb_context *tdb, int hash, tdb_len_t length, > struct tdb_record *rec); >-int tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); >+ >+int _tdb_oob(struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe); >+ >+static inline int tdb_oob( >+ struct tdb_context *tdb, tdb_off_t off, tdb_len_t len, int probe) >+{ >+ if (likely((off + len >= off) && (off + len <= tdb->map_size))) { >+ return 0; >+ } >+ return _tdb_oob(tdb, off, len, probe); >+} >+ >+ > int tdb_ofs_read(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); > int tdb_ofs_write(struct tdb_context *tdb, tdb_off_t offset, tdb_off_t *d); > int tdb_lock_record(struct tdb_context *tdb, tdb_off_t off); >-- >2.17.1 > > >From c14427253e8cb4aab951ded527258e6f67fc4452 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 20 Aug 2019 14:55:27 +0200 >Subject: [PATCH 028/376] tdb: Release tdb 1.4.2 > >* Build fixes >* Improve the performance by inlining the tdb_oob() checks > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Tue Aug 20 14:45:41 UTC 2019 on sn-devel-184 > >(cherry picked from commit 60cba7b3a17104da1543d59609f50c6638880dd1) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Aug 21 09:57:08 UTC 2019 on sn-devel-184 >--- > lib/tdb/ABI/tdb-1.4.2.sigs | 73 ++++++++++++++++++++++++++++++++++++++ > lib/tdb/wscript | 2 +- > 2 files changed, 74 insertions(+), 1 deletion(-) > create mode 100644 lib/tdb/ABI/tdb-1.4.2.sigs > >diff --git a/lib/tdb/ABI/tdb-1.4.2.sigs b/lib/tdb/ABI/tdb-1.4.2.sigs >new file mode 100644 >index 00000000000..e2b0427c347 >--- /dev/null >+++ b/lib/tdb/ABI/tdb-1.4.2.sigs >@@ -0,0 +1,73 @@ >+tdb_add_flags: void (struct tdb_context *, unsigned int) >+tdb_append: int (struct tdb_context *, TDB_DATA, TDB_DATA) >+tdb_chainlock: int (struct tdb_context *, TDB_DATA) >+tdb_chainlock_mark: int (struct tdb_context *, TDB_DATA) >+tdb_chainlock_nonblock: int (struct tdb_context *, TDB_DATA) >+tdb_chainlock_read: int (struct tdb_context *, TDB_DATA) >+tdb_chainlock_read_nonblock: int (struct tdb_context *, TDB_DATA) >+tdb_chainlock_unmark: int (struct tdb_context *, TDB_DATA) >+tdb_chainunlock: int (struct tdb_context *, TDB_DATA) >+tdb_chainunlock_read: int (struct tdb_context *, TDB_DATA) >+tdb_check: int (struct tdb_context *, int (*)(TDB_DATA, TDB_DATA, void *), void *) >+tdb_close: int (struct tdb_context *) >+tdb_delete: int (struct tdb_context *, TDB_DATA) >+tdb_dump_all: void (struct tdb_context *) >+tdb_enable_seqnum: void (struct tdb_context *) >+tdb_error: enum TDB_ERROR (struct tdb_context *) >+tdb_errorstr: const char *(struct tdb_context *) >+tdb_exists: int (struct tdb_context *, TDB_DATA) >+tdb_fd: int (struct tdb_context *) >+tdb_fetch: TDB_DATA (struct tdb_context *, TDB_DATA) >+tdb_firstkey: TDB_DATA (struct tdb_context *) >+tdb_freelist_size: int (struct tdb_context *) >+tdb_get_flags: int (struct tdb_context *) >+tdb_get_logging_private: void *(struct tdb_context *) >+tdb_get_seqnum: int (struct tdb_context *) >+tdb_hash_size: int (struct tdb_context *) >+tdb_increment_seqnum_nonblock: void (struct tdb_context *) >+tdb_jenkins_hash: unsigned int (TDB_DATA *) >+tdb_lock_nonblock: int (struct tdb_context *, int, int) >+tdb_lockall: int (struct tdb_context *) >+tdb_lockall_mark: int (struct tdb_context *) >+tdb_lockall_nonblock: int (struct tdb_context *) >+tdb_lockall_read: int (struct tdb_context *) >+tdb_lockall_read_nonblock: int (struct tdb_context *) >+tdb_lockall_unmark: int (struct tdb_context *) >+tdb_log_fn: tdb_log_func (struct tdb_context *) >+tdb_map_size: size_t (struct tdb_context *) >+tdb_name: const char *(struct tdb_context *) >+tdb_nextkey: TDB_DATA (struct tdb_context *, TDB_DATA) >+tdb_null: dptr = 0xXXXX, dsize = 0 >+tdb_open: struct tdb_context *(const char *, int, int, int, mode_t) >+tdb_open_ex: struct tdb_context *(const char *, int, int, int, mode_t, const struct tdb_logging_context *, tdb_hash_func) >+tdb_parse_record: int (struct tdb_context *, TDB_DATA, int (*)(TDB_DATA, TDB_DATA, void *), void *) >+tdb_printfreelist: int (struct tdb_context *) >+tdb_remove_flags: void (struct tdb_context *, unsigned int) >+tdb_reopen: int (struct tdb_context *) >+tdb_reopen_all: int (int) >+tdb_repack: int (struct tdb_context *) >+tdb_rescue: int (struct tdb_context *, void (*)(TDB_DATA, TDB_DATA, void *), void *) >+tdb_runtime_check_for_robust_mutexes: bool (void) >+tdb_set_logging_function: void (struct tdb_context *, const struct tdb_logging_context *) >+tdb_set_max_dead: void (struct tdb_context *, int) >+tdb_setalarm_sigptr: void (struct tdb_context *, volatile sig_atomic_t *) >+tdb_store: int (struct tdb_context *, TDB_DATA, TDB_DATA, int) >+tdb_storev: int (struct tdb_context *, TDB_DATA, const TDB_DATA *, int, int) >+tdb_summary: char *(struct tdb_context *) >+tdb_transaction_active: bool (struct tdb_context *) >+tdb_transaction_cancel: int (struct tdb_context *) >+tdb_transaction_commit: int (struct tdb_context *) >+tdb_transaction_prepare_commit: int (struct tdb_context *) >+tdb_transaction_start: int (struct tdb_context *) >+tdb_transaction_start_nonblock: int (struct tdb_context *) >+tdb_transaction_write_lock_mark: int (struct tdb_context *) >+tdb_transaction_write_lock_unmark: int (struct tdb_context *) >+tdb_traverse: int (struct tdb_context *, tdb_traverse_func, void *) >+tdb_traverse_chain: int (struct tdb_context *, unsigned int, tdb_traverse_func, void *) >+tdb_traverse_key_chain: int (struct tdb_context *, TDB_DATA, tdb_traverse_func, void *) >+tdb_traverse_read: int (struct tdb_context *, tdb_traverse_func, void *) >+tdb_unlock: int (struct tdb_context *, int, int) >+tdb_unlockall: int (struct tdb_context *) >+tdb_unlockall_read: int (struct tdb_context *) >+tdb_validate_freelist: int (struct tdb_context *, int *) >+tdb_wipe_all: int (struct tdb_context *) >diff --git a/lib/tdb/wscript b/lib/tdb/wscript >index ece44f82e33..1ab0e8d334a 100644 >--- a/lib/tdb/wscript >+++ b/lib/tdb/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tdb' >-VERSION = '1.4.1' >+VERSION = '1.4.2' > > import sys, os > >-- >2.17.1 > > >From 521240aa3728d61e8b768c6e5f20146afaf97e2f Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Wed, 21 Aug 2019 12:34:58 +0200 >Subject: [PATCH 029/376] VERSION: Disable GIT_SNAPSHOT for the 4.11.0rc2 > release. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/VERSION b/VERSION >index c70b521219c..12f04435907 100644 >--- a/VERSION >+++ b/VERSION >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=2 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=yes >+SAMBA_VERSION_IS_GIT_SNAPSHOT=no > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From ea38596181c8e64f87019d7cfa48b0e0dc225e70 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Wed, 21 Aug 2019 12:36:23 +0200 >Subject: [PATCH 030/376] VERSION: Bump version up to 4.11.0rc3... > >and re-enable GIT_SNAPSHOT. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index 12f04435907..67ae2000ebf 100644 >--- a/VERSION >+++ b/VERSION >@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= > # e.g. SAMBA_VERSION_RC_RELEASE=1 # > # -> "3.0.0rc1" # > ######################################################## >-SAMBA_VERSION_RC_RELEASE=2 >+SAMBA_VERSION_RC_RELEASE=3 > > ######################################################## > # To mark SVN snapshots this should be set to 'yes' # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=2 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=no >+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From 72d79334a53917bd3ee6521bcea2a551906712da Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Fri, 7 Jun 2019 12:55:32 -0700 >Subject: [PATCH 031/376] Revert "nfs4acl: Fix owner mapping with ID_TYPE_BOTH" > >This reverts commit 5d4f7bfda579cecb123cfb1d7130688f1d1c98b7. > >That patch broke the case with ID_TYPE_BOTH where a file is owned by a >group (e.g. using autorid and having a file owned by >BUILTIN\Administrators). In this case, the ACE entry for the group gets >mapped a to a user ACL entry and the group no longer has access (as in >the user's token the group is not mapped to a uid). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 42bd3a72a2525aa8a918f4bf7067b30ce8e0e197) >--- > source3/modules/nfs4_acls.c | 9 +-------- > 1 file changed, 1 insertion(+), 8 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 7776caa16d2..6db5a6db6d9 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -723,14 +723,7 @@ static bool smbacl4_fill_ace4( > uid_t uid; > gid_t gid; > >- /* >- * ID_TYPE_BOTH returns both uid and gid. Explicitly >- * check for ownerUID to allow the mapping of the >- * owner to a special entry in this idmap config. >- */ >- if (sid_to_uid(&ace_nt->trustee, &uid) && uid == ownerUID) { >- ace_v4->who.uid = uid; >- } else if (sid_to_gid(&ace_nt->trustee, &gid)) { >+ if (sid_to_gid(&ace_nt->trustee, &gid)) { > ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; > ace_v4->who.gid = gid; > } else if (sid_to_uid(&ace_nt->trustee, &uid)) { >-- >2.17.1 > > >From 9e82d8ae7fa94228656e9a82d5a7d41d5cb0a4e3 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 11 Jun 2019 16:15:10 -0700 >Subject: [PATCH 032/376] nfs4_acls: Remove fsp from smbacl4_win2nfs4 > >Only the information whether the ACL is for a file or a directory is >required. Replacing the fsp with a flag is clearer and allows for unit >testing of the mapping functions. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit a06486bb110d04a90b66a0bca4b1b600ef3c0ebf) >--- > source3/modules/nfs4_acls.c | 22 ++++++++++------------ > 1 file changed, 10 insertions(+), 12 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 6db5a6db6d9..5543b3a7f58 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -648,7 +648,7 @@ static SMB_ACE4PROP_T *smbacl4_find_equal_special( > > > static bool smbacl4_fill_ace4( >- const struct smb_filename *filename, >+ bool is_directory, > const struct smbacl4_vfs_params *params, > uid_t ownerUID, > gid_t ownerGID, >@@ -670,8 +670,7 @@ static bool smbacl4_fill_ace4( > ace_nt->flags); > > /* remove inheritance flags on files */ >- if (VALID_STAT(filename->st) && >- !S_ISDIR(filename->st.st_ex_mode)) { >+ if (!is_directory) { > DEBUG(10, ("Removing inheritance flags from a file\n")); > ace_v4->aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE| > SMB_ACE4_DIRECTORY_INHERIT_ACE| >@@ -732,9 +731,8 @@ static bool smbacl4_fill_ace4( > &global_sid_Unix_NFS) == 0) { > return false; > } else { >- DEBUG(1, ("nfs4_acls.c: file [%s]: could not " >+ DEBUG(1, ("nfs4_acls.c: could not " > "convert %s to uid or gid\n", >- filename->base_name, > dom_sid_str_buf(&ace_nt->trustee, &buf))); > return false; > } >@@ -855,7 +853,7 @@ static int smbacl4_substitute_simple( > > static struct SMB4ACL_T *smbacl4_win2nfs4( > TALLOC_CTX *mem_ctx, >- const files_struct *fsp, >+ bool is_directory, > const struct security_acl *dacl, > const struct smbacl4_vfs_params *pparams, > uid_t ownerUID, >@@ -864,7 +862,6 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > { > struct SMB4ACL_T *theacl; > uint32_t i; >- const char *filename = fsp->fsp_name->base_name; > > DEBUG(10, ("smbacl4_win2nfs4 invoked\n")); > >@@ -876,12 +873,11 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > SMB_ACE4PROP_T ace_v4; > bool addNewACE = true; > >- if (!smbacl4_fill_ace4(fsp->fsp_name, pparams, >+ if (!smbacl4_fill_ace4(is_directory, pparams, > ownerUID, ownerGID, > dacl->aces + i, &ace_v4)) { > struct dom_sid_buf buf; >- DEBUG(3, ("Could not fill ace for file %s, SID %s\n", >- filename, >+ DEBUG(3, ("Could not fill ace for file, SID %s\n", > dom_sid_str_buf(&((dacl->aces+i)->trustee), > &buf))); > continue; >@@ -916,7 +912,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > { > struct smbacl4_vfs_params params; > struct SMB4ACL_T *theacl = NULL; >- bool result; >+ bool result, is_directory; > > SMB_STRUCT_STAT sbuf; > bool set_acl_as_root = false; >@@ -951,6 +947,8 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > return map_nt_error_from_unix(errno); > } > >+ is_directory = S_ISDIR(sbuf.st_ex_mode); >+ > if (pparams->do_chown) { > /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */ > NTSTATUS status = unpack_nt_owners(fsp->conn, &newUID, &newGID, >@@ -998,7 +996,7 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > return NT_STATUS_OK; > } > >- theacl = smbacl4_win2nfs4(frame, fsp, psd->dacl, pparams, >+ theacl = smbacl4_win2nfs4(frame, is_directory, psd->dacl, pparams, > sbuf.st_ex_uid, sbuf.st_ex_gid); > if (!theacl) { > TALLOC_FREE(frame); >-- >2.17.1 > > >From 88b0461ca0d120d39e10a8765d2f25429ef2faab Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:22:13 -0700 >Subject: [PATCH 033/376] selftest: Start implementing unit test for nfs4_acls > >Existing smbtorture tests set and query ACLs through SMB, only working >with the DACLs in the Security Descriptors, but never check the NFSv4 >ACL representation. This patch introduces a unit test to verify the >mapping between between Security Descriptors and NFSv4 ACLs. As the >mapping code queries id mappings, the id mapping cache is first primed >with the mappings used by the tests and those mappings are removed again >during teardown. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 8fb906a1860452a320c79ac87917a97303729c19) >--- > source3/modules/test_nfs4_acls.c | 136 +++++++++++++++++++++++++++++++ > source3/modules/wscript_build | 5 ++ > source3/selftest/tests.py | 4 + > 3 files changed, 145 insertions(+) > create mode 100644 source3/modules/test_nfs4_acls.c > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >new file mode 100644 >index 00000000000..557f27c7428 >--- /dev/null >+++ b/source3/modules/test_nfs4_acls.c >@@ -0,0 +1,136 @@ >+/* >+ * Unix SMB/CIFS implementation. >+ * >+ * Unit test for NFS4 ACL handling >+ * >+ * Copyright (C) Christof Schmitt 2019 >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 3 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program; if not, see <http://www.gnu.org/licenses/>. >+ */ >+ >+#include "nfs4_acls.c" >+#include "librpc/gen_ndr/idmap.h" >+#include "idmap_cache.h" >+#include <cmocka.h> >+ >+struct test_sids { >+ const char *sid_str; >+ struct unixid unix_id; >+} test_sids[] = { >+ { "S-1-5-2-123-456-789-100", { 1000, ID_TYPE_UID }}, >+ { "S-1-5-2-123-456-789-101", { 1001, ID_TYPE_GID }}, >+ { "S-1-5-2-123-456-789-102", { 1002, ID_TYPE_BOTH }}, >+ { SID_CREATOR_OWNER, { 1003, ID_TYPE_UID }}, >+ { SID_CREATOR_GROUP, { 1004, ID_TYPE_GID }}, >+ { "S-1-5-2-123-456-789-103", { 1000, ID_TYPE_GID }}, >+ { "S-1-5-2-123-456-789-104", { 1005, ID_TYPE_BOTH }}, >+ { "S-1-5-2-123-456-789-105", { 1006, ID_TYPE_BOTH }}, >+ { "S-1-5-2-123-456-789-106", { 1007, ID_TYPE_BOTH }}, >+}; >+ >+static int group_setup(void **state) >+{ >+ struct dom_sid *sids = NULL; >+ int i; >+ >+ sids = talloc_array(NULL, struct dom_sid, ARRAY_SIZE(test_sids)); >+ assert_non_null(sids); >+ >+ for (i = 0; i < ARRAY_SIZE(test_sids); i++) { >+ assert_true(dom_sid_parse(test_sids[i].sid_str, &sids[i])); >+ idmap_cache_set_sid2unixid(&sids[i], &test_sids[i].unix_id); >+ } >+ >+ *state = sids; >+ >+ return 0; >+ >+} >+ >+static int group_teardown(void **state) >+{ >+ struct dom_sid *sids = *state; >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(test_sids); i++) { >+ assert_true(idmap_cache_del_sid(&sids[i])); >+ } >+ >+ TALLOC_FREE(sids); >+ *state = NULL; >+ >+ return 0; >+} >+ >+/* >+ * Run this as first test to verify that the id mappings used by other >+ * tests are available in the cache. >+ */ >+static void test_cached_id_mappings(void **state) >+{ >+ struct dom_sid *sids = *state; >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(test_sids); i++) { >+ struct dom_sid *sid = &sids[i]; >+ struct unixid *unix_id = &test_sids[i].unix_id; >+ uid_t uid; >+ gid_t gid; >+ >+ switch(unix_id->type) { >+ case ID_TYPE_UID: >+ assert_true(sid_to_uid(sid, &uid)); >+ assert_int_equal(uid, unix_id->id); >+ assert_false(sid_to_gid(sid, &gid)); >+ break; >+ case ID_TYPE_GID: >+ assert_false(sid_to_uid(sid, &uid)); >+ assert_true(sid_to_gid(sid, &gid)); >+ assert_int_equal(gid, unix_id->id); >+ break; >+ case ID_TYPE_BOTH: >+ assert_true(sid_to_uid(sid, &uid)); >+ assert_int_equal(uid, unix_id->id); >+ assert_true(sid_to_gid(sid, &gid)); >+ assert_int_equal(gid, unix_id->id); >+ break; >+ default: >+ fail_msg("Unknown id type %d\n", unix_id->type); >+ break; >+ } >+ } >+} >+ >+int main(int argc, char **argv) >+{ >+ const struct CMUnitTest tests[] = { >+ cmocka_unit_test(test_cached_id_mappings), >+ }; >+ >+ cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >+ >+ if (argc != 2) { >+ print_error("Usage: %s smb.conf\n", argv[0]); >+ exit(1); >+ } >+ >+ /* >+ * Initialize enough of the Samba internals to have the >+ * mappings tests work. >+ */ >+ talloc_stackframe(); >+ lp_load_global(argv[1]); >+ >+ return cmocka_run_group_tests(tests, group_setup, group_teardown); >+} >diff --git a/source3/modules/wscript_build b/source3/modules/wscript_build >index 5e0047da917..80b0ce9ff90 100644 >--- a/source3/modules/wscript_build >+++ b/source3/modules/wscript_build >@@ -4,6 +4,11 @@ bld.SAMBA3_SUBSYSTEM('NFS4_ACLS', > source='nfs4_acls.c', > deps='samba-util tdb') > >+bld.SAMBA3_BINARY('test_nfs4_acls', >+ source='test_nfs4_acls.c', >+ deps='smbd_base cmocka', >+ install=False) >+ > bld.SAMBA3_SUBSYSTEM('vfs_acl_common', > source='vfs_acl_common.c') > >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index 78f58bdb30c..9569aa9ae00 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -427,6 +427,10 @@ if with_pthreadpool: > "script/tests/test_libwbclient_threads.sh"), > "$DOMAIN", "$DC_USERNAME"]) > >+plantestsuite("samba3.test_nfs4_acl", "none", >+ [os.path.join(bindir(), "test_nfs4_acls"), >+ "$SMB_CONF_PATH"]) >+ > plantestsuite( > "samba3.resolvconf", "none", > [os.path.join(samba3srcdir, "script/tests/test_resolvconf.sh")]) >-- >2.17.1 > > >From 526da3f215a12dca398ad6c615541e5edb359dae Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:23:40 -0700 >Subject: [PATCH 034/376] test_nfs4_acls: Add tests for mapping of empty ACLs > >This is a fairly simple test that ensures the mapping of empty ACLs >(without any ACL entries) is always done the same way. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 00f494b25f4e1d1aecf6191523e30f20a90b1e4f) >--- > source3/modules/test_nfs4_acls.c | 53 ++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 557f27c7428..18322afb4a0 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -112,10 +112,63 @@ static void test_cached_id_mappings(void **state) > } > } > >+static void test_empty_nfs4_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], false, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 0); >+ assert_null(dacl_aces); >+ >+ TALLOC_FREE(frame); >+} >+ >+static void test_empty_dacl_to_nfs4(void **state) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, 0, NULL); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, ¶ms, 1001, 1002); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 0); >+ assert_null(smb_first_ace4(nfs4_acl)); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { > cmocka_unit_test(test_cached_id_mappings), >+ cmocka_unit_test(test_empty_nfs4_to_dacl), >+ cmocka_unit_test(test_empty_dacl_to_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 4120b8dcbe8e8de5cb4db7e09a8916f4ab4d4493 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:25:33 -0700 >Subject: [PATCH 035/376] test_nfs4_acls: Add tests for mapping of ACL types > >Add testcases for mapping the type field (ALLOW or DENY) between NFSv4 >ACLs and security descriptors. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit dd5934797526ebb4c6f3027a809401dad3abf701) >--- > source3/modules/test_nfs4_acls.c | 107 +++++++++++++++++++++++++++++++ > 1 file changed, 107 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 18322afb4a0..b29714d23e3 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -163,12 +163,119 @@ static void test_empty_dacl_to_nfs4(void **state) > assert_null(smb_first_ace4(nfs4_acl)); > } > >+struct ace_dacl_type_mapping { >+ uint32_t nfs4_type; >+ enum security_ace_type dacl_type; >+} ace_dacl_type_mapping[] = { >+ { SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, SEC_ACE_TYPE_ACCESS_ALLOWED }, >+ { SMB_ACE4_ACCESS_DENIED_ACE_TYPE, SEC_ACE_TYPE_ACCESS_DENIED }, >+}; >+ >+static void test_acl_type_nfs4_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.uid = 1000, >+ .aceType = ace_dacl_type_mapping[i].nfs4_type, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[2], &sids[3], false, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 1); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, >+ ace_dacl_type_mapping[i].dacl_type); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ >+static void test_acl_type_dacl_to_nfs4(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(ace_dacl_type_mapping); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[1]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], &sids[0], >+ ace_dacl_type_mapping[i].dacl_type, >+ SEC_FILE_READ_DATA, 0); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, ¶ms, >+ 101, 102); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, 0); >+ assert_int_equal(nfs4_ace->aceType, >+ ace_dacl_type_mapping[i].nfs4_type); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { > cmocka_unit_test(test_cached_id_mappings), > cmocka_unit_test(test_empty_nfs4_to_dacl), > cmocka_unit_test(test_empty_dacl_to_nfs4), >+ cmocka_unit_test(test_acl_type_nfs4_to_dacl), >+ cmocka_unit_test(test_acl_type_dacl_to_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From c1eb8ec5c3313cebee8dc4ea3643459ced76a2b1 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:28:31 -0700 >Subject: [PATCH 036/376] test_nfs4_acls: Add test for flags mapping from NFS4 > ACL to DACL > >Add testcase for the mapping of inheritance flags when mapping from a >NFSv4 ACL to a DACL in the security descriptor. The mapping is different >between files and directories, as some inheritance flags should never be >present for files. Some defined flags like SUCCESSFUL_ACCESS are also >not mapped at this point, also verify this behavior. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 16eb61a900c6749c2554d635ce2dd903f5de1704) >--- > source3/modules/test_nfs4_acls.c | 87 ++++++++++++++++++++++++++++++++ > 1 file changed, 87 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index b29714d23e3..47ae14d0e65 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -268,6 +268,92 @@ static void test_acl_type_dacl_to_nfs4(void **state) > TALLOC_FREE(frame); > } > >+struct ace_flag_mapping_nfs4_to_dacl { >+ bool is_directory; >+ uint32_t nfs4_flag; >+ uint32_t dacl_flag; >+} ace_flags_nfs4_to_dacl[] = { >+ { true, SMB_ACE4_FILE_INHERIT_ACE, >+ SEC_ACE_FLAG_OBJECT_INHERIT }, >+ { false, SMB_ACE4_FILE_INHERIT_ACE, >+ 0 }, >+ { true, SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ SEC_ACE_FLAG_CONTAINER_INHERIT }, >+ { false, SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ 0 }, >+ { true, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE, >+ SEC_ACE_FLAG_NO_PROPAGATE_INHERIT }, >+ { false, SMB_ACE4_NO_PROPAGATE_INHERIT_ACE, >+ SEC_ACE_FLAG_NO_PROPAGATE_INHERIT }, >+ { true, SMB_ACE4_INHERIT_ONLY_ACE, >+ SEC_ACE_FLAG_INHERIT_ONLY }, >+ { false, SMB_ACE4_INHERIT_ONLY_ACE, >+ SEC_ACE_FLAG_INHERIT_ONLY }, >+ { true, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG, >+ 0 }, >+ { false, SMB_ACE4_SUCCESSFUL_ACCESS_ACE_FLAG, >+ 0 }, >+ { true, SMB_ACE4_FAILED_ACCESS_ACE_FLAG, >+ 0 }, >+ { false, SMB_ACE4_FAILED_ACCESS_ACE_FLAG, >+ 0 }, >+ { true, SMB_ACE4_INHERITED_ACE, >+ SEC_ACE_FLAG_INHERITED_ACE }, >+ { false, SMB_ACE4_INHERITED_ACE, >+ SEC_ACE_FLAG_INHERITED_ACE }, >+}; >+ >+static void test_ace_flags_nfs4_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ SMB_ACE4PROP_T nfs4_ace; >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(ace_flags_nfs4_to_dacl); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ bool is_directory; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.uid = 1000, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = ace_flags_nfs4_to_dacl[i].nfs4_flag, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ is_directory = ace_flags_nfs4_to_dacl[i].is_directory; >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[2], &sids[3], is_directory, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 1); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, >+ ace_flags_nfs4_to_dacl[i].dacl_flag); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -276,6 +362,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_empty_dacl_to_nfs4), > cmocka_unit_test(test_acl_type_nfs4_to_dacl), > cmocka_unit_test(test_acl_type_dacl_to_nfs4), >+ cmocka_unit_test(test_ace_flags_nfs4_to_dacl), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From ec532e3ed55d94252a23639aad6937118fcf68f1 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:30:12 -0700 >Subject: [PATCH 037/376] test_nfs4_acls: Add test for flags mapping from DACL > to NFS4 ACL > >Add testcase for the mapping of inheritance flags from the DACL in the >security descriptor to the NFSv4 ACL. The mapping is different for files >and directories as some inheritance flags should not be present for >files. Also other flags are not mapped at all, verify this behavior. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit bccd2612761e26ee2514935d56927b2c0c000859) >--- > source3/modules/test_nfs4_acls.c | 87 ++++++++++++++++++++++++++++++++ > 1 file changed, 87 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 47ae14d0e65..a0e7db41b70 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -354,6 +354,92 @@ static void test_ace_flags_nfs4_to_dacl(void **state) > TALLOC_FREE(frame); > } > >+struct ace_flag_mapping_dacl_to_nfs4 { >+ bool is_directory; >+ uint32_t dacl_flag; >+ uint32_t nfs4_flag; >+} ace_flags_dacl_to_nfs4[] = { >+ { true, SEC_ACE_FLAG_OBJECT_INHERIT, >+ SMB_ACE4_FILE_INHERIT_ACE }, >+ { false, SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0 }, >+ { true, SEC_ACE_FLAG_CONTAINER_INHERIT, >+ SMB_ACE4_DIRECTORY_INHERIT_ACE }, >+ { false, SEC_ACE_FLAG_CONTAINER_INHERIT, >+ 0 }, >+ { true, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT, >+ SMB_ACE4_NO_PROPAGATE_INHERIT_ACE }, >+ { false, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT, >+ 0 }, >+ { true, SEC_ACE_FLAG_INHERIT_ONLY, >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ { false, SEC_ACE_FLAG_INHERIT_ONLY, >+ 0 }, >+ { true, SEC_ACE_FLAG_INHERITED_ACE, >+ SMB_ACE4_INHERITED_ACE }, >+ { false, SEC_ACE_FLAG_INHERITED_ACE, >+ SMB_ACE4_INHERITED_ACE }, >+ { true, SEC_ACE_FLAG_SUCCESSFUL_ACCESS, >+ 0 }, >+ { false, SEC_ACE_FLAG_SUCCESSFUL_ACCESS, >+ 0 }, >+ { true, SEC_ACE_FLAG_FAILED_ACCESS, >+ 0 }, >+ { false, SEC_ACE_FLAG_FAILED_ACCESS, >+ 0 }, >+}; >+ >+static void test_ace_flags_dacl_to_nfs4(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(ace_flags_dacl_to_nfs4); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ bool is_directory; >+ struct security_ace dacl_aces[1]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ ace_flags_dacl_to_nfs4[i].dacl_flag); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ is_directory = ace_flags_dacl_to_nfs4[i].is_directory; >+ nfs4_acl = smbacl4_win2nfs4(frame, is_directory, dacl, ¶ms, >+ 101, 102); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ ace_flags_dacl_to_nfs4[i].nfs4_flag); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -363,6 +449,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_acl_type_nfs4_to_dacl), > cmocka_unit_test(test_acl_type_dacl_to_nfs4), > cmocka_unit_test(test_ace_flags_nfs4_to_dacl), >+ cmocka_unit_test(test_ace_flags_dacl_to_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 014ae431e64166de6c97660cfbfc6c90c52b532e Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:33:29 -0700 >Subject: [PATCH 038/376] test_nfs4_acls: Add test for mapping permissions from > NFS4 ACL to DACL > >Add testcase for mapping permissions from the NFSv4 ACL to DACL in the >security descriptor. The mapping is simple as each permission bit exists >on both sides. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 1767027b44a9e4ebd865022e3f8abb0c72bf15c6) >--- > source3/modules/test_nfs4_acls.c | 77 ++++++++++++++++++++++++++++++++ > 1 file changed, 77 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index a0e7db41b70..42a69453f5a 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -440,6 +440,82 @@ static void test_ace_flags_dacl_to_nfs4(void **state) > TALLOC_FREE(frame); > } > >+struct ace_perm_mapping { >+ uint32_t nfs4_perm; >+ uint32_t dacl_perm; >+} perm_table_nfs4_to_dacl[] = { >+ { SMB_ACE4_READ_DATA, SEC_FILE_READ_DATA }, >+ { SMB_ACE4_LIST_DIRECTORY, SEC_DIR_LIST }, >+ { SMB_ACE4_WRITE_DATA, SEC_FILE_WRITE_DATA }, >+ { SMB_ACE4_ADD_FILE, SEC_DIR_ADD_FILE }, >+ { SMB_ACE4_APPEND_DATA, SEC_FILE_APPEND_DATA }, >+ { SMB_ACE4_ADD_SUBDIRECTORY, SEC_DIR_ADD_SUBDIR, }, >+ { SMB_ACE4_READ_NAMED_ATTRS, SEC_FILE_READ_EA }, >+ { SMB_ACE4_READ_NAMED_ATTRS, SEC_DIR_READ_EA }, >+ { SMB_ACE4_WRITE_NAMED_ATTRS, SEC_FILE_WRITE_EA }, >+ { SMB_ACE4_WRITE_NAMED_ATTRS, SEC_DIR_WRITE_EA }, >+ { SMB_ACE4_EXECUTE, SEC_FILE_EXECUTE }, >+ { SMB_ACE4_EXECUTE, SEC_DIR_TRAVERSE }, >+ { SMB_ACE4_DELETE_CHILD, SEC_DIR_DELETE_CHILD }, >+ { SMB_ACE4_READ_ATTRIBUTES, SEC_FILE_READ_ATTRIBUTE }, >+ { SMB_ACE4_READ_ATTRIBUTES, SEC_DIR_READ_ATTRIBUTE }, >+ { SMB_ACE4_WRITE_ATTRIBUTES, SEC_FILE_WRITE_ATTRIBUTE }, >+ { SMB_ACE4_WRITE_ATTRIBUTES, SEC_DIR_WRITE_ATTRIBUTE }, >+ { SMB_ACE4_DELETE, SEC_STD_DELETE }, >+ { SMB_ACE4_READ_ACL, SEC_STD_READ_CONTROL }, >+ { SMB_ACE4_WRITE_ACL, SEC_STD_WRITE_DAC, }, >+ { SMB_ACE4_WRITE_OWNER, SEC_STD_WRITE_OWNER }, >+ { SMB_ACE4_SYNCHRONIZE, SEC_STD_SYNCHRONIZE }, >+}; >+ >+static void test_nfs4_permissions_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.uid = 1000, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = perm_table_nfs4_to_dacl[i].nfs4_perm, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], false, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 1); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_int_equal(dacl_aces[0].access_mask, >+ perm_table_nfs4_to_dacl[i].dacl_perm); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -450,6 +526,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_acl_type_dacl_to_nfs4), > cmocka_unit_test(test_ace_flags_nfs4_to_dacl), > cmocka_unit_test(test_ace_flags_dacl_to_nfs4), >+ cmocka_unit_test(test_nfs4_permissions_to_dacl), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 368c370dc2f82b03da2e910e1116f5afee064c29 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:35:34 -0700 >Subject: [PATCH 039/376] test_nfs4_acls: Add test for mapping permissions from > DACL to NFS4 ACL > >Add testcase for mapping the permission flags from the DACL in the >Security Descriptor to a NFSv4 ACL. The mapping is straight-forward as >the same permission bits exist for Security Descriptors and NFSv4 ACLs. >In addition, the code also maps from the generic DACL permissions to a >set of NFSv4 permissions, also verify this mapping. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit e4840e680744bd860beedeb5123704c3c0d6a4d7) >--- > source3/modules/test_nfs4_acls.c | 106 +++++++++++++++++++++++++++++++ > 1 file changed, 106 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 42a69453f5a..d77eceb1b88 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -516,6 +516,111 @@ static void test_nfs4_permissions_to_dacl(void **state) > TALLOC_FREE(frame); > } > >+struct ace_perm_mapping_dacl_to_nfs4 { >+ uint32_t dacl_perm; >+ uint32_t nfs4_perm; >+} perm_table_dacl_to_nfs4[] = { >+ { SEC_FILE_READ_DATA, SMB_ACE4_READ_DATA, }, >+ { SEC_DIR_LIST, SMB_ACE4_LIST_DIRECTORY, }, >+ { SEC_FILE_WRITE_DATA, SMB_ACE4_WRITE_DATA, }, >+ { SEC_DIR_ADD_FILE, SMB_ACE4_ADD_FILE, }, >+ { SEC_FILE_APPEND_DATA, SMB_ACE4_APPEND_DATA, }, >+ { SEC_DIR_ADD_SUBDIR, SMB_ACE4_ADD_SUBDIRECTORY, }, >+ { SEC_FILE_READ_EA, SMB_ACE4_READ_NAMED_ATTRS, }, >+ { SEC_DIR_READ_EA, SMB_ACE4_READ_NAMED_ATTRS, }, >+ { SEC_FILE_WRITE_EA, SMB_ACE4_WRITE_NAMED_ATTRS, }, >+ { SEC_DIR_WRITE_EA, SMB_ACE4_WRITE_NAMED_ATTRS, }, >+ { SEC_FILE_EXECUTE, SMB_ACE4_EXECUTE, }, >+ { SEC_DIR_TRAVERSE, SMB_ACE4_EXECUTE, }, >+ { SEC_DIR_DELETE_CHILD, SMB_ACE4_DELETE_CHILD, }, >+ { SEC_FILE_READ_ATTRIBUTE, SMB_ACE4_READ_ATTRIBUTES, }, >+ { SEC_DIR_READ_ATTRIBUTE, SMB_ACE4_READ_ATTRIBUTES, }, >+ { SEC_FILE_WRITE_ATTRIBUTE, SMB_ACE4_WRITE_ATTRIBUTES, }, >+ { SEC_DIR_WRITE_ATTRIBUTE, SMB_ACE4_WRITE_ATTRIBUTES, }, >+ { SEC_STD_DELETE, SMB_ACE4_DELETE, }, >+ { SEC_STD_READ_CONTROL, SMB_ACE4_READ_ACL, }, >+ { SEC_STD_WRITE_DAC, SMB_ACE4_WRITE_ACL, }, >+ { SEC_STD_WRITE_OWNER, SMB_ACE4_WRITE_OWNER, }, >+ { SEC_STD_SYNCHRONIZE, SMB_ACE4_SYNCHRONIZE, }, >+ { SEC_GENERIC_READ, SMB_ACE4_READ_ACL| >+ SMB_ACE4_READ_DATA| >+ SMB_ACE4_READ_ATTRIBUTES| >+ SMB_ACE4_READ_NAMED_ATTRS| >+ SMB_ACE4_SYNCHRONIZE }, >+ { SEC_GENERIC_WRITE, SMB_ACE4_WRITE_ACL| >+ SMB_ACE4_WRITE_DATA| >+ SMB_ACE4_WRITE_ATTRIBUTES| >+ SMB_ACE4_WRITE_NAMED_ATTRS| >+ SMB_ACE4_SYNCHRONIZE }, >+ { SEC_GENERIC_EXECUTE, SMB_ACE4_READ_ACL| >+ SMB_ACE4_READ_ATTRIBUTES| >+ SMB_ACE4_EXECUTE| >+ SMB_ACE4_SYNCHRONIZE }, >+ { SEC_GENERIC_ALL, SMB_ACE4_DELETE| >+ SMB_ACE4_READ_ACL| >+ SMB_ACE4_WRITE_ACL| >+ SMB_ACE4_WRITE_OWNER| >+ SMB_ACE4_SYNCHRONIZE| >+ SMB_ACE4_WRITE_ATTRIBUTES| >+ SMB_ACE4_READ_ATTRIBUTES| >+ SMB_ACE4_EXECUTE| >+ SMB_ACE4_READ_NAMED_ATTRS| >+ SMB_ACE4_WRITE_NAMED_ATTRS| >+ SMB_ACE4_WRITE_DATA| >+ SMB_ACE4_APPEND_DATA| >+ SMB_ACE4_READ_DATA| >+ SMB_ACE4_DELETE_CHILD }, >+}; >+ >+static void test_dacl_permissions_to_nfs4(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(perm_table_nfs4_to_dacl); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ struct security_ace dacl_aces[1]; >+ struct security_acl *dacl; >+ >+ init_sec_ace(&dacl_aces[0], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, >+ perm_table_dacl_to_nfs4[i].dacl_perm, 0); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, false, dacl, ¶ms, >+ 101, 102); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, 0); >+ assert_int_equal(nfs4_ace->aceMask, >+ perm_table_dacl_to_nfs4[i].nfs4_perm); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -527,6 +632,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_ace_flags_nfs4_to_dacl), > cmocka_unit_test(test_ace_flags_dacl_to_nfs4), > cmocka_unit_test(test_nfs4_permissions_to_dacl), >+ cmocka_unit_test(test_dacl_permissions_to_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From dda9e525c55c3602060fffc773e1d31b524ba93f Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:46:23 -0700 >Subject: [PATCH 040/376] test_nfs4_acls: Add test for mapping of special NFS4 > ACL entries to DACL entries > >In addition to entries for users and groups, NFSv4 ACLs have the concept >of entries for "special" entries. Only the "owner", "group" and >"everyone" entries are currently used in the ACL mapping. > >Add a testcase that verifies the mapping from NFSv4 "special" entries to >the DACL in the security descriptor. Verify that only "owner", "group" >and "everyone" are mapped and all other "special" entries are ignored. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit f86148948c7f89307a34e31f6ddede6923149d34) >--- > source3/modules/test_nfs4_acls.c | 139 +++++++++++++++++++++++++++++++ > 1 file changed, 139 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index d77eceb1b88..5b5b37adc82 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -621,6 +621,144 @@ static void test_dacl_permissions_to_nfs4(void **state) > TALLOC_FREE(frame); > } > >+/* >+ * Create NFS4 ACL with all possible "special" entries. Verify that >+ * the ones that should be mapped to a DACL are mapped and the other >+ * ones are ignored. >+ */ >+static void test_special_nfs4_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_OWNER, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_GROUP, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_EVERYONE, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_APPEND_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_INTERACTIVE, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_READ_NAMED_ATTRS, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_NETWORK, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_WRITE_NAMED_ATTRS, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_DIALUP, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_EXECUTE, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_BATCH, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_READ_ATTRIBUTES, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_ANONYMOUS, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_WRITE_ATTRIBUTES, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_AUTHENTICATED, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_READ_ACL, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_SERVICE, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = SMB_ACE4_WRITE_ACL, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], false, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 3); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ >+ assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[1].flags, 0); >+ assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[1])); >+ >+ assert_int_equal(dacl_aces[2].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[2].flags, 0); >+ assert_int_equal(dacl_aces[2].access_mask, SEC_FILE_APPEND_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[2].trustee, &global_sid_World)); >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -633,6 +771,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_ace_flags_dacl_to_nfs4), > cmocka_unit_test(test_nfs4_permissions_to_dacl), > cmocka_unit_test(test_dacl_permissions_to_nfs4), >+ cmocka_unit_test(test_special_nfs4_to_dacl), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From aa466a0104d95f0a512c5d740df1c17a06116bd4 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:53:15 -0700 >Subject: [PATCH 041/376] test_nfs4_acls: Add test for mapping from DACL to > special NFS4 ACL entries > >Add testcase for mapping from entries in the DACL security descriptor to >"special" entries in the NFSv4 ACL. Verify that the WORLD well-known SID >maps to "everyone" in the NFSv4 ACL. Verify that the "Unix NFS" SID is >ignored, as there is no meaningful mapping for this entry. Verify that >SID entries matching the owner or group are mapped to "special owner" >or "special group", but only if no inheritance flags are used. "special >owner" and "special group" with inheritance flags have the meaning of >CREATOR OWNER and CREATOR GROUP and will be tested in another testcase. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 1f1fa5bde2c76636c1beec39c21067b252ea10be) >--- > source3/modules/test_nfs4_acls.c | 108 +++++++++++++++++++++++++++++++ > 1 file changed, 108 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 5b5b37adc82..46119f83dc4 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -759,6 +759,113 @@ static void test_special_nfs4_to_dacl(void **state) > TALLOC_FREE(frame); > } > >+static void test_dacl_to_special_nfs4(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[6]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_dontcare, >+ .map_full_control = true, >+ }; >+ >+ /* >+ * global_Sid_World is mapped to EVERYONE. >+ */ >+ init_sec_ace(&dacl_aces[0], &global_sid_World, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA, 0); >+ /* >+ * global_sid_Unix_NFS is ignored. >+ */ >+ init_sec_ace(&dacl_aces[1], &global_sid_Unix_NFS, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, 0); >+ /* >+ * Anything that maps to owner or owning group with inheritance flags >+ * is NOT mapped to special owner or special group. >+ */ >+ init_sec_ace(&dacl_aces[2], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[3], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); >+ init_sec_ace(&dacl_aces[4], &sids[1], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[5], &sids[1], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, 1000, 1001); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 5); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_EVERYONE); >+ assert_int_equal(nfs4_ace->aceFlags, 0); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_WRITE_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->who.gid, 1001); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE); >+ assert_int_equal(nfs4_ace->who.gid, 1001); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -772,6 +879,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_nfs4_permissions_to_dacl), > cmocka_unit_test(test_dacl_permissions_to_nfs4), > cmocka_unit_test(test_special_nfs4_to_dacl), >+ cmocka_unit_test(test_dacl_to_special_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 4e46dbc7749753b9d6d89ef9aa995cb49e53969a Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:55:59 -0700 >Subject: [PATCH 042/376] test_nfs4_acls: Add test for mapping CREATOR entries > to NFS4 ACL entries > >Add testcase for mapping DACL entries CREATOR OWNER and CREATOR GROUP >with inheritance flag in the security descriptor to NFSv4 "special >owner" and "special group" entries. This is the correct mapping for >these entries as inheriting "special owner" and "special group" grants >permissions to the actual owner and owning group of the new file or >directory, similar to what CREATOR entries do. > >The other side is that CREATOR entries without any inheritance flags do >not make sense, so these are not mapped to NFSv4 ACL entries. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit bfcc19b705f83bdd5cf665fd4daf43e7eae997a9) >--- > source3/modules/test_nfs4_acls.c | 108 +++++++++++++++++++++++++++++++ > 1 file changed, 108 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 46119f83dc4..dcdcb89823f 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -866,6 +866,113 @@ static void test_dacl_to_special_nfs4(void **state) > TALLOC_FREE(frame); > } > >+struct creator_ace_flags { >+ uint32_t dacl_flags; >+ uint32_t nfs4_flags; >+} creator_ace_flags[] = { >+ { 0, 0 }, >+ >+ { SEC_ACE_FLAG_INHERIT_ONLY, 0 }, >+ >+ { SEC_ACE_FLAG_CONTAINER_INHERIT, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ >+ { SEC_ACE_FLAG_CONTAINER_INHERIT| >+ SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ >+ { SEC_ACE_FLAG_OBJECT_INHERIT, SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ { SEC_ACE_FLAG_OBJECT_INHERIT| >+ SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ >+ { SEC_ACE_FLAG_CONTAINER_INHERIT| >+ SEC_ACE_FLAG_OBJECT_INHERIT, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+ >+ { SEC_ACE_FLAG_CONTAINER_INHERIT| >+ SEC_ACE_FLAG_OBJECT_INHERIT| >+ SEC_ACE_FLAG_INHERIT_ONLY, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE }, >+}; >+ >+static void test_dacl_creator_to_nfs4(void **state) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(creator_ace_flags); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[2]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], &global_sid_Creator_Owner, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ creator_ace_flags[i].dacl_flags); >+ init_sec_ace(&dacl_aces[1], &global_sid_Creator_Group, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ creator_ace_flags[i].dacl_flags); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, >+ 101, 102); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ >+ if (creator_ace_flags[i].nfs4_flags == 0) { >+ /* >+ * CREATOR OWNER and CREATOR GROUP not mapped >+ * in thise case. >+ */ >+ assert_null(smb_first_ace4(nfs4_acl)); >+ } else { >+ assert_int_equal(smb_get_naces(nfs4_acl), 2); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->who.special_id, >+ SMB_ACE4_WHO_OWNER); >+ assert_int_equal(nfs4_ace->aceFlags, >+ creator_ace_flags[i].nfs4_flags); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->who.special_id, >+ SMB_ACE4_WHO_GROUP); >+ assert_int_equal(nfs4_ace->aceFlags, >+ creator_ace_flags[i].nfs4_flags); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ } >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -880,6 +987,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_permissions_to_nfs4), > cmocka_unit_test(test_special_nfs4_to_dacl), > cmocka_unit_test(test_dacl_to_special_nfs4), >+ cmocka_unit_test(test_dacl_creator_to_nfs4), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 61002278b801a1d5814954c44371e73d0a2eee43 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 11:57:45 -0700 >Subject: [PATCH 043/376] test_nfs4_acls: Add test for mapping from NFS4 to > DACL CREATOR entries > >Add testcase for mapping from NFSv4 ACL entries for "special owner" and >"special group" to DACL entries in the security descriptor. Each NFSv4 >entry here with INHERIT_ONLY maps directly to a CREATOR OWNER or CREATOR >GROUP entry in the DACL. Entries without INHERIT_ONLY map to the CREATOR >entry and an additional explicit entry granting permission on the >current object. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3c9cda0f6d80258ef0c2a80d6e24dfb650fea1b1) >--- > source3/modules/test_nfs4_acls.c | 122 +++++++++++++++++++++++++++++++ > 1 file changed, 122 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index dcdcb89823f..e4e5f1f8b6e 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -973,6 +973,127 @@ static void test_dacl_creator_to_nfs4(void **state) > TALLOC_FREE(frame); > } > >+struct creator_owner_nfs4_to_dacl { >+ uint32_t special_id; >+ uint32_t nfs4_ace_flags; >+ uint32_t dacl_ace_flags; >+} creator_owner_nfs4_to_dacl[] = { >+ { SMB_ACE4_WHO_OWNER, >+ SMB_ACE4_FILE_INHERIT_ACE, >+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY }, >+ { SMB_ACE4_WHO_OWNER, >+ SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY }, >+ { SMB_ACE4_WHO_OWNER, >+ SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| >+ SEC_ACE_FLAG_INHERIT_ONLY }, >+ { SMB_ACE4_WHO_GROUP, >+ SMB_ACE4_FILE_INHERIT_ACE, >+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY }, >+ { SMB_ACE4_WHO_GROUP, >+ SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY }, >+ { SMB_ACE4_WHO_GROUP, >+ SMB_ACE4_FILE_INHERIT_ACE|SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT| >+ SEC_ACE_FLAG_INHERIT_ONLY }, >+}; >+ >+static void test_nfs4_to_dacl_creator(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(creator_owner_nfs4_to_dacl); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces, *creator_dacl_ace; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id >+ = creator_owner_nfs4_to_dacl[i].special_id, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags >+ = creator_owner_nfs4_to_dacl[i].nfs4_ace_flags, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], true, >+ &dacl_aces, &good_aces)); >+ assert_non_null(dacl_aces); >+ >+ if (creator_owner_nfs4_to_dacl[i].nfs4_ace_flags & >+ SMB_ACE4_INHERIT_ONLY_ACE) { >+ /* >+ * Only one ACE entry for the CREATOR ACE entry. >+ */ >+ assert_int_equal(good_aces, 1); >+ creator_dacl_ace = &dacl_aces[0]; >+ } else { >+ /* >+ * This creates an additional ACE entry for >+ * the permissions on the current object. >+ */ >+ assert_int_equal(good_aces, 2); >+ >+ assert_int_equal(dacl_aces[0].type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_int_equal(dacl_aces[0].access_mask, >+ SEC_FILE_READ_DATA); >+ >+ if (creator_owner_nfs4_to_dacl[i].special_id == >+ SMB_ACE4_WHO_OWNER) { >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, >+ &sids[0])); >+ } >+ >+ if (creator_owner_nfs4_to_dacl[i].special_id == >+ SMB_ACE4_WHO_GROUP) { >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, >+ &sids[1])); >+ } >+ >+ creator_dacl_ace = &dacl_aces[1]; >+ } >+ >+ assert_int_equal(creator_dacl_ace->type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(creator_dacl_ace->flags, >+ creator_owner_nfs4_to_dacl[i].dacl_ace_flags); >+ assert_int_equal(creator_dacl_ace->access_mask, >+ SEC_FILE_READ_DATA); >+ if (creator_owner_nfs4_to_dacl[i].special_id == >+ SMB_ACE4_WHO_OWNER) { >+ assert_true(dom_sid_equal(&creator_dacl_ace->trustee, >+ &global_sid_Creator_Owner)); >+ } >+ >+ if (creator_owner_nfs4_to_dacl[i].special_id == >+ SMB_ACE4_WHO_GROUP) { >+ assert_true(dom_sid_equal(&creator_dacl_ace->trustee, >+ &global_sid_Creator_Group)); >+ } >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -988,6 +1109,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_special_nfs4_to_dacl), > cmocka_unit_test(test_dacl_to_special_nfs4), > cmocka_unit_test(test_dacl_creator_to_nfs4), >+ cmocka_unit_test(test_nfs4_to_dacl_creator), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 31d60e8cf2c27e7c05f18b087db5c5aa48075b79 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:02:58 -0700 >Subject: [PATCH 044/376] test_nfs4_acls: Add test for 'map full control' > option > >"map full control" when enabled adds the DELETE_CHILD permission, when >all other permissions are present. This allows Windows clients to >display the "FULL CONTROL" permissions. > >Add a testcase that verifies this mapping when mapping from NFSv4 ACL to >the DACL in the security descriptor. Also verify that switching the >option off disables this behavior. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 30677df4dac4ebfcf4e3198db33f14be37948197) >--- > source3/modules/test_nfs4_acls.c | 82 ++++++++++++++++++++++++++++++++ > 1 file changed, 82 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index e4e5f1f8b6e..733217b1f2e 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1094,6 +1094,87 @@ static void test_nfs4_to_dacl_creator(void **state) > TALLOC_FREE(frame); > } > >+struct nfs4_to_dacl_map_full_control{ >+ bool is_dir; >+ bool config; >+ bool delete_child_added; >+} nfs4_to_dacl_full_control[] = { >+ { true, true, false }, >+ { true, false, false }, >+ { false, true, true }, >+ { false, false, false }, >+}; >+ >+static void test_full_control_nfs4_to_dacl(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(nfs4_to_dacl_full_control); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = nfs4_to_dacl_full_control[i].config, >+ }; >+ const uint32_t nfs4_ace_mask_except_deletes = >+ SMB_ACE4_READ_DATA|SMB_ACE4_WRITE_DATA| >+ SMB_ACE4_APPEND_DATA|SMB_ACE4_READ_NAMED_ATTRS| >+ SMB_ACE4_WRITE_NAMED_ATTRS|SMB_ACE4_EXECUTE| >+ SMB_ACE4_READ_ATTRIBUTES|SMB_ACE4_WRITE_ATTRIBUTES| >+ SMB_ACE4_READ_ACL|SMB_ACE4_WRITE_ACL| >+ SMB_ACE4_WRITE_OWNER|SMB_ACE4_SYNCHRONIZE; >+ const uint32_t dacl_ace_mask_except_deletes = >+ SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA| >+ SEC_FILE_APPEND_DATA|SEC_FILE_READ_EA| >+ SEC_FILE_WRITE_EA|SEC_FILE_EXECUTE| >+ SEC_FILE_READ_ATTRIBUTE|SEC_FILE_WRITE_ATTRIBUTE| >+ SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC| >+ SEC_STD_WRITE_OWNER|SEC_STD_SYNCHRONIZE; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.uid = 1000, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = 0, >+ .aceMask = nfs4_ace_mask_except_deletes, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true( >+ smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], >+ nfs4_to_dacl_full_control[i].is_dir, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 1); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ if (nfs4_to_dacl_full_control[i].delete_child_added) { >+ assert_int_equal(dacl_aces[0].access_mask, >+ dacl_ace_mask_except_deletes| >+ SEC_DIR_DELETE_CHILD); >+ } else { >+ assert_int_equal(dacl_aces[0].access_mask, >+ dacl_ace_mask_except_deletes); >+ } >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1110,6 +1191,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_to_special_nfs4), > cmocka_unit_test(test_dacl_creator_to_nfs4), > cmocka_unit_test(test_nfs4_to_dacl_creator), >+ cmocka_unit_test(test_full_control_nfs4_to_dacl), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 490d13557a4c2bd7046c85080930c0fc9d0d7ee0 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:07:36 -0700 >Subject: [PATCH 045/376] test_nfs4_acls: Add test for acedup settings > >The NFSv4 ACL mapping code has a setting nfs4:acedup. Depending on the >setting, when mapping from DACLs to NFSv4 ACLs, duplicate ACL entries >are either merged, ignored or rejected. Add a testcase that has >duplicate ACL entries and verify the expected behavior for all possible >settings of the nfs4:acedup option. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 9671bf2b9f055012057620207624aa2f4ea6833e) >--- > source3/modules/test_nfs4_acls.c | 124 +++++++++++++++++++++++++++++++ > 1 file changed, 124 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 733217b1f2e..c4f3d8052e4 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1175,6 +1175,129 @@ static void test_full_control_nfs4_to_dacl(void **state) > TALLOC_FREE(frame); > } > >+struct acedup_settings { >+ enum smbacl4_acedup_enum setting; >+} acedup_settings[] = { >+ { e_dontcare }, >+ { e_reject }, >+ { e_ignore }, >+ { e_merge }, >+}; >+ >+static void test_dacl_to_nfs4_acedup_settings(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(acedup_settings); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[2]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = acedup_settings[i].setting, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[1], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, >+ 101, 102); >+ >+ switch(params.acedup) { >+ case e_dontcare: >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 2); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, >+ SMB_ACE4_WRITE_DATA); >+ break; >+ >+ case e_reject: >+ assert_null(nfs4_acl); >+ assert_int_equal(errno, EINVAL); >+ break; >+ >+ case e_ignore: >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ break; >+ >+ case e_merge: >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, >+ SMB_ACE4_READ_DATA| >+ SMB_ACE4_WRITE_DATA); >+ break; >+ >+ default: >+ fail_msg("Unexpected value for acedup: %d\n", >+ params.acedup); >+ }; >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1192,6 +1315,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_creator_to_nfs4), > cmocka_unit_test(test_nfs4_to_dacl_creator), > cmocka_unit_test(test_full_control_nfs4_to_dacl), >+ cmocka_unit_test(test_dacl_to_nfs4_acedup_settings), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 4022997f0305ff39db9af2ecb24bd1a2aa9ee0a6 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:09:04 -0700 >Subject: [PATCH 046/376] test_nfs4_acls: Add test for matching DACL entries > for acedup > >The NFSv4 mapping code has a config option nfs4:acedup for the mapping >path from DACLs to NFSv4 ACLs. Part of this codepath is detecting >duplicate ACL entries. Add a testcase with different ACL entries and >verify that only exactly matching entries are detected as duplicates and >treated accordingly. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit f55cdf42a14f314102f2e13cb06d4db48c08ad4b) >--- > source3/modules/test_nfs4_acls.c | 122 +++++++++++++++++++++++++++++++ > 1 file changed, 122 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index c4f3d8052e4..80078311ce8 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1298,6 +1298,127 @@ static void test_dacl_to_nfs4_acedup_settings(void **state) > TALLOC_FREE(frame); > } > >+struct acedup_match { >+ int sid_idx1; >+ enum security_ace_type type1; >+ uint32_t ace_mask1; >+ uint8_t flag1; >+ int sid_idx2; >+ enum security_ace_type type2; >+ uint32_t ace_mask2; >+ uint8_t flag2; >+ bool match; >+} acedup_match[] = { >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ true }, >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 1, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ false }, >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SEC_ACE_TYPE_ACCESS_DENIED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ false }, >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ true }, >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT, >+ false }, >+ { 0, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ 5, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT, >+ false }, >+}; >+ >+static void test_dacl_to_nfs4_acedup_match(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ for (i = 0; i < ARRAY_SIZE(acedup_match); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[2]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_ignore, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], >+ &sids[acedup_match[i].sid_idx1], >+ acedup_match[i].type1, >+ acedup_match[i].ace_mask1, >+ acedup_match[i].flag1); >+ init_sec_ace(&dacl_aces[1], >+ &sids[acedup_match[i].sid_idx2], >+ acedup_match[i].type2, >+ acedup_match[i].ace_mask2, >+ acedup_match[i].flag2); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, >+ 101, 102); >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ >+ if (acedup_match[i].match) { >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ } else { >+ assert_int_equal(smb_get_naces(nfs4_acl), 2); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->who.uid, 1000); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ } >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1316,6 +1437,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_nfs4_to_dacl_creator), > cmocka_unit_test(test_full_control_nfs4_to_dacl), > cmocka_unit_test(test_dacl_to_nfs4_acedup_settings), >+ cmocka_unit_test(test_dacl_to_nfs4_acedup_match), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From d3a9648eb63a0624ba2c500ab0a1c477140912ec Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:16:08 -0700 >Subject: [PATCH 047/376] test_nfs4_acls: Add test for mapping from DACL to > NFS4 ACL with config special > >The mapping code between NFSv4 ACLs and security descriptors still has >the deprecated config setting "nfs4:mode = special". This should not be >used as it has security problems: All entries matching owner or group >are mapped to "special owner" or "special group", which can change its >meaning when being inherited to a new file or directory with different >owner and owning group. > >This mode should eventually be removed, but as long as it still exists >add testcases to verify the expected behavior. This patch adds the >testcase for "nfs4:mode = special" when mapping from the DACL in the >security descriptor to the NFSv4 ACL. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 7ae06d96eb59722154d30e21949f9dba4f2f0bc6) >--- > source3/modules/test_nfs4_acls.c | 119 +++++++++++++++++++++++++++++++ > 1 file changed, 119 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 80078311ce8..eda2fe56d32 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1419,6 +1419,124 @@ static void test_dacl_to_nfs4_acedup_match(void **state) > TALLOC_FREE(frame); > } > >+static void test_dacl_to_nfs4_config_special(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[6]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_special, >+ .do_chown = true, >+ .acedup = e_dontcare, >+ .map_full_control = true, >+ }; >+ >+ /* >+ * global_sid_Creator_Owner or global_sid_Special_Group is NOT mapped >+ * to SMB_ACE4_ID_SPECIAL. >+ */ >+ init_sec_ace(&dacl_aces[0], &global_sid_Creator_Owner, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[1], &global_sid_Creator_Group, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_WRITE_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT); >+ /* >+ * Anything that maps to owner or owning group with inheritance flags >+ * IS mapped to special owner or special group. >+ */ >+ init_sec_ace(&dacl_aces[2], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[3], &sids[0], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); >+ init_sec_ace(&dacl_aces[4], &sids[1], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_OBJECT_INHERIT); >+ init_sec_ace(&dacl_aces[5], &sids[1], >+ SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_FILE_READ_DATA, >+ SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, 1000, 1001); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 6); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->who.uid, 1003); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, 0); >+ assert_int_equal(nfs4_ace->aceFlags, >+ SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_DIRECTORY_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->who.gid, 1004); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_WRITE_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_OWNER); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE); >+ assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_OWNER); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_FILE_INHERIT_ACE); >+ assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_GROUP); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, SMB_ACE4_ID_SPECIAL); >+ assert_int_equal(nfs4_ace->aceFlags, SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE); >+ assert_int_equal(nfs4_ace->who.special_id, SMB_ACE4_WHO_GROUP); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1438,6 +1556,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_full_control_nfs4_to_dacl), > cmocka_unit_test(test_dacl_to_nfs4_acedup_settings), > cmocka_unit_test(test_dacl_to_nfs4_acedup_match), >+ cmocka_unit_test(test_dacl_to_nfs4_config_special), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 2de4919e8a33334cf7c10b9aa407f4c7cff4e53d Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:23:02 -0700 >Subject: [PATCH 048/376] test_nfs4_acls: Add test for mapping from NFS4 to > DACL in config mode special > >The mapping code between NFSv4 ACLs and security descriptors still has >the deprecated config setting "nfs4:mode = special". This should not be >used as it has security problems: All entries matching owner or group >are mapped to "special owner" or "special group", which can change its >meaning when being inherited to a new file or directory with different >owner and owning group. > >This mode should eventually be removed, but as long as it still exists >add testcases to verify the expected behavior. This patch adds the >testcase for "nfs4:mode = special" when mapping from the NFS4 ACL to the >DACL in the security descriptor. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 829c5ea99685c0629fd67ed0528897534ff35b36) >--- > source3/modules/test_nfs4_acls.c | 63 ++++++++++++++++++++++++++++++++ > 1 file changed, 63 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index eda2fe56d32..341bf179ea9 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1537,6 +1537,68 @@ static void test_dacl_to_nfs4_config_special(void **state) > TALLOC_FREE(frame); > } > >+static void test_nfs4_to_dacl_config_special(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_special, >+ .do_chown = true, >+ .acedup = e_dontcare, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ /* >+ * In config mode special, this is not mapped to Creator Owner >+ */ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_OWNER, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_FILE_INHERIT_ACE, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ /* >+ * In config mode special, this is not mapped to Creator Group >+ */ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = SMB_ACE4_ID_SPECIAL, >+ .who.special_id = SMB_ACE4_WHO_GROUP, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_DIRECTORY_INHERIT_ACE, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], true, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 2); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, SEC_ACE_FLAG_OBJECT_INHERIT); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[0])); >+ >+ assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[1].flags, SEC_ACE_FLAG_CONTAINER_INHERIT); >+ assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[1])); >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1557,6 +1619,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_to_nfs4_acedup_settings), > cmocka_unit_test(test_dacl_to_nfs4_acedup_match), > cmocka_unit_test(test_dacl_to_nfs4_config_special), >+ cmocka_unit_test(test_nfs4_to_dacl_config_special), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 7d73c37ae7bbc102dab469f5709b1a54de7a0a74 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 12:50:42 -0700 >Subject: [PATCH 049/376] test_nfs4_acls: Add test for mapping from NFS4 ACL to > DACL with IDMAP_TYPE_BOTH > >When id mappings use IDMAP_TYPE_BOTH, the NFSv4 ACL mapping code is not >aware whether a particular entry is for a user or a group. The >underlying assumption then is that is should not matter, as both the ACL >mapping maps everything to NFSv4 ACL group entries and the user's token >will contain gid entries for the groups. > >Add a testcase to verify that when mapping from NFSv4 ACL entries to >DACLs with IDMAP_TYPE_BOTH, all entries are mapped as expected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 86480410aec1d2331c65826a13f909492165a291) >--- > source3/modules/test_nfs4_acls.c | 67 ++++++++++++++++++++++++++++++++ > 1 file changed, 67 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 341bf179ea9..964af4ff057 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1599,6 +1599,72 @@ static void test_nfs4_to_dacl_config_special(void **state) > TALLOC_FREE(frame); > } > >+struct nfs_to_dacl_idmap_both { >+ uint32_t nfs4_flags; >+ uint32_t nfs4_id; >+ struct dom_sid *sid; >+}; >+ >+static void test_nfs4_to_dacl_idmap_type_both(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ struct nfs_to_dacl_idmap_both nfs_to_dacl_idmap_both[] = { >+ { 0, 1002, &sids[2] }, >+ { SMB_ACE4_IDENTIFIER_GROUP, 1002, &sids[2] }, >+ { 0, 1005, &sids[6] }, >+ { SMB_ACE4_IDENTIFIER_GROUP, 1005, &sids[6] }, >+ }; >+ >+ for (i = 0; i < ARRAY_SIZE(nfs_to_dacl_idmap_both); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct security_ace *dacl_aces; >+ SMB_ACE4PROP_T nfs4_ace; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = nfs_to_dacl_idmap_both[i].nfs4_flags, >+ .aceMask = SMB_ACE4_READ_DATA, >+ }; >+ >+ if (nfs_to_dacl_idmap_both[i].nfs4_flags & >+ SMB_ACE4_IDENTIFIER_GROUP) { >+ nfs4_ace.who.gid = nfs_to_dacl_idmap_both[i].nfs4_id; >+ } else { >+ nfs4_ace.who.uid = nfs_to_dacl_idmap_both[i].nfs4_id; >+ } >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[2], &sids[2], >+ false, &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 1); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, >+ SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, 0); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_READ_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, >+ nfs_to_dacl_idmap_both[i].sid)); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1620,6 +1686,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_to_nfs4_acedup_match), > cmocka_unit_test(test_dacl_to_nfs4_config_special), > cmocka_unit_test(test_nfs4_to_dacl_config_special), >+ cmocka_unit_test(test_nfs4_to_dacl_idmap_type_both), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 0313f1552f9665ed485aa2c7224f491be8511eff Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 13:04:44 -0700 >Subject: [PATCH 050/376] test_nfs4_acls: Add test for mapping from DACL to > NFS4 ACL with IDMAP_TYPE_BOTH > >When id mappings use IDMAP_TYPE_BOTH, the NFSv4 ACL mapping code is not >aware whether a particular entry is for a user or a group. The >underlying assumption then is that is should not matter, as both the ACL >mapping maps everything to NFSv4 ACL group entries and the user's token >will contain gid entries for the groups. > >Add a testcase to verify that when mapping from DACLS to NFSv4 ACL >entries with IDMAP_TYPE_BOTH, all entries are mapped as expected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 38331b00521ef764893a74add01758f14567d901) >--- > source3/modules/test_nfs4_acls.c | 85 ++++++++++++++++++++++++++++++++ > 1 file changed, 85 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 964af4ff057..d7152a0737a 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1665,6 +1665,90 @@ static void test_nfs4_to_dacl_idmap_type_both(void **state) > TALLOC_FREE(frame); > } > >+struct dacl_to_nfs4_idmap_both { >+ struct dom_sid *sid; >+ uint32_t dacl_flags; >+ uint32_t nfs4_flags; >+ uint32_t nfs4_ace_flags; >+ uint32_t nfs4_id; >+}; >+ >+/* >+ * IDMAP_TYPE_BOTH always creates group entries. >+ */ >+static void test_dacl_to_nfs4_idmap_type_both(void **state) >+{ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ int i; >+ >+ struct dacl_to_nfs4_idmap_both dacl_to_nfs4_idmap_both[] = { >+ { &sids[2], 0, >+ SMB_ACE4_ID_SPECIAL, SMB_ACE4_IDENTIFIER_GROUP, SMB_ACE4_WHO_GROUP }, >+ { &sids[2], SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002 }, >+ { &sids[6], 0, >+ 0, SMB_ACE4_IDENTIFIER_GROUP, 1005 }, >+ { &sids[6], SEC_ACE_FLAG_OBJECT_INHERIT, >+ 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1005 }, >+ }; >+ >+ for (i = 0; i < ARRAY_SIZE(dacl_to_nfs4_idmap_both); i++) { >+ struct SMB4ACL_T *nfs4_acl; >+ struct SMB4ACE_T *nfs4_ace_container; >+ SMB_ACE4PROP_T *nfs4_ace; >+ struct security_ace dacl_aces[1]; >+ struct security_acl *dacl; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_merge, >+ .map_full_control = true, >+ }; >+ >+ init_sec_ace(&dacl_aces[0], dacl_to_nfs4_idmap_both[i].sid, >+ SEC_ACE_TYPE_ACCESS_ALLOWED, >+ SEC_FILE_READ_DATA, >+ dacl_to_nfs4_idmap_both[i].dacl_flags); >+ dacl = make_sec_acl(frame, SECURITY_ACL_REVISION_ADS, >+ ARRAY_SIZE(dacl_aces), dacl_aces); >+ assert_non_null(dacl); >+ >+ nfs4_acl = smbacl4_win2nfs4(frame, true, dacl, ¶ms, >+ 1002, 1002); >+ >+ assert_non_null(nfs4_acl); >+ assert_int_equal(smbacl4_get_controlflags(nfs4_acl), >+ SEC_DESC_SELF_RELATIVE); >+ assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ >+ nfs4_ace_container = smb_first_ace4(nfs4_acl); >+ assert_non_null(nfs4_ace_container); >+ assert_null(smb_next_ace4(nfs4_ace_container)); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, >+ dacl_to_nfs4_idmap_both[i].nfs4_flags); >+ assert_int_equal(nfs4_ace->aceFlags, >+ dacl_to_nfs4_idmap_both[i].nfs4_ace_flags); >+ if (nfs4_ace->flags & SMB_ACE4_ID_SPECIAL) { >+ assert_int_equal(nfs4_ace->who.special_id, >+ dacl_to_nfs4_idmap_both[i].nfs4_id); >+ } else if (nfs4_ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) { >+ assert_int_equal(nfs4_ace->who.gid, >+ dacl_to_nfs4_idmap_both[i].nfs4_id); >+ } else { >+ assert_int_equal(nfs4_ace->who.uid, >+ dacl_to_nfs4_idmap_both[i].nfs4_id); >+ } >+ assert_int_equal(nfs4_ace->aceType, >+ SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1687,6 +1771,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_dacl_to_nfs4_config_special), > cmocka_unit_test(test_nfs4_to_dacl_config_special), > cmocka_unit_test(test_nfs4_to_dacl_idmap_type_both), >+ cmocka_unit_test(test_dacl_to_nfs4_idmap_type_both), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From 6d88ab39e8ed469a9279870d88b28c568ce3a687 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 26 Jun 2019 13:24:16 -0700 >Subject: [PATCH 051/376] nfs4_acls: Use sids_to_unixids to lookup uid or gid > >This is the newer API to lookup id mappings and will make it easier to >add to the IDMAP_TYPE_BOTH case. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit d9a2ff559e1ad953141b1118a9e370496f1f61fa) >--- > source3/modules/nfs4_acls.c | 20 ++++++++++++++------ > 1 file changed, 14 insertions(+), 6 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 5543b3a7f58..4069c9310ed 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -21,6 +21,7 @@ > #include "smbd/smbd.h" > #include "nfs4_acls.h" > #include "librpc/gen_ndr/ndr_security.h" >+#include "librpc/gen_ndr/idmap.h" > #include "../libcli/security/dom_sid.h" > #include "../libcli/security/security.h" > #include "dbwrap/dbwrap.h" >@@ -719,14 +720,21 @@ static bool smbacl4_fill_ace4( > return false; > } > } else { >- uid_t uid; >- gid_t gid; >+ struct unixid unixid; >+ bool ok; > >- if (sid_to_gid(&ace_nt->trustee, &gid)) { >+ ok = sids_to_unixids(&ace_nt->trustee, 1, &unixid); >+ if (!ok) { >+ DBG_WARNING("Could not convert %s to uid or gid.\n", >+ dom_sid_str_buf(&ace_nt->trustee, &buf)); >+ return false; >+ } >+ >+ if (unixid.type == ID_TYPE_GID || unixid.type == ID_TYPE_BOTH) { > ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >- ace_v4->who.gid = gid; >- } else if (sid_to_uid(&ace_nt->trustee, &uid)) { >- ace_v4->who.uid = uid; >+ ace_v4->who.gid = unixid.id; >+ } else if (unixid.type == ID_TYPE_UID) { >+ ace_v4->who.uid = unixid.id; > } else if (dom_sid_compare_domain(&ace_nt->trustee, > &global_sid_Unix_NFS) == 0) { > return false; >-- >2.17.1 > > >From b1b8e37881f5583f5b7770c46a8db4162e614884 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Mon, 15 Jul 2019 13:15:32 -0700 >Subject: [PATCH 052/376] nfs4_acls: Use switch/case for checking idmap type > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit f198a0867e71f248d4887ab0b6f2832123b16d11) >--- > source3/modules/nfs4_acls.c | 27 ++++++++++++++++++--------- > 1 file changed, 18 insertions(+), 9 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 4069c9310ed..f8861e9058b 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -730,18 +730,27 @@ static bool smbacl4_fill_ace4( > return false; > } > >- if (unixid.type == ID_TYPE_GID || unixid.type == ID_TYPE_BOTH) { >+ if (dom_sid_compare_domain(&ace_nt->trustee, >+ &global_sid_Unix_NFS) == 0) { >+ return false; >+ } >+ >+ switch (unixid.type) { >+ case ID_TYPE_BOTH: > ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; > ace_v4->who.gid = unixid.id; >- } else if (unixid.type == ID_TYPE_UID) { >+ break; >+ case ID_TYPE_GID: >+ ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >+ ace_v4->who.gid = unixid.id; >+ break; >+ case ID_TYPE_UID: > ace_v4->who.uid = unixid.id; >- } else if (dom_sid_compare_domain(&ace_nt->trustee, >- &global_sid_Unix_NFS) == 0) { >- return false; >- } else { >- DEBUG(1, ("nfs4_acls.c: could not " >- "convert %s to uid or gid\n", >- dom_sid_str_buf(&ace_nt->trustee, &buf))); >+ break; >+ case ID_TYPE_NOT_SPECIFIED: >+ default: >+ DBG_WARNING("Could not convert %s to uid or gid.\n", >+ dom_sid_str_buf(&ace_nt->trustee, &buf)); > return false; > } > } >-- >2.17.1 > > >From e08f9b24097f8b5d08dcca3ee98017b114fcea99 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 25 Jun 2019 15:21:06 -0700 >Subject: [PATCH 053/376] nfs4_acls: Use correct type when checking ownerGID > >uid and gid are members of the same union so this makes no difference, >but for type correctness and readability use the gid to check for >ownerGID. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3b3d722ce579c19c7b08d06a3adea275537545dc) >--- > source3/modules/nfs4_acls.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index f8861e9058b..b2ba4d1d701 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -856,7 +856,7 @@ static int smbacl4_substitute_simple( > > if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && > ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP && >- ace->who.uid == ownerGID && >+ ace->who.gid == ownerGID && > !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) && > !(ace->aceFlags & SMB_ACE4_FILE_INHERIT_ACE) && > !(ace->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) { >-- >2.17.1 > > >From 6661fecf2676fc0ff30a86a2332be95fa76f89ed Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 26 Jun 2019 13:20:17 -0700 >Subject: [PATCH 054/376] nfs4_acls: Add helper function for checking INHERIT > flags. > >This avoids some code duplication. Do not make this static, as it will >be used in a later patch. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmit <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 336e8668c1cc3682cb3c198eb6dc49baf522a79a) >--- > source3/modules/nfs4_acls.c | 15 +++++++++------ > source3/modules/nfs4_acls.h | 2 ++ > 2 files changed, 11 insertions(+), 6 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index b2ba4d1d701..bab73a5cb58 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -255,6 +255,13 @@ bool smbacl4_set_controlflags(struct SMB4ACL_T *acl, uint16_t controlflags) > return true; > } > >+bool nfs_ace_is_inherit(SMB_ACE4PROP_T *ace) >+{ >+ return ace->aceFlags & (SMB_ACE4_INHERIT_ONLY_ACE| >+ SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_DIRECTORY_INHERIT_ACE); >+} >+ > static int smbacl4_GetFileOwner(struct connection_struct *conn, > const struct smb_filename *smb_fname, > SMB_STRUCT_STAT *psbuf) >@@ -846,9 +853,7 @@ static int smbacl4_substitute_simple( > if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && > !(ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) && > ace->who.uid == ownerUID && >- !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) && >- !(ace->aceFlags & SMB_ACE4_FILE_INHERIT_ACE) && >- !(ace->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) { >+ !nfs_ace_is_inherit(ace)) { > ace->flags |= SMB_ACE4_ID_SPECIAL; > ace->who.special_id = SMB_ACE4_WHO_OWNER; > DEBUG(10,("replaced with special owner ace\n")); >@@ -857,9 +862,7 @@ static int smbacl4_substitute_simple( > if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && > ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP && > ace->who.gid == ownerGID && >- !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) && >- !(ace->aceFlags & SMB_ACE4_FILE_INHERIT_ACE) && >- !(ace->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) { >+ !nfs_ace_is_inherit(ace)) { > ace->flags |= SMB_ACE4_ID_SPECIAL; > ace->who.special_id = SMB_ACE4_WHO_GROUP; > DEBUG(10,("replaced with special group ace\n")); >diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h >index a73b3154f0f..d0cf2d0f1fb 100644 >--- a/source3/modules/nfs4_acls.h >+++ b/source3/modules/nfs4_acls.h >@@ -143,6 +143,8 @@ uint16_t smbacl4_get_controlflags(struct SMB4ACL_T *theacl); > > bool smbacl4_set_controlflags(struct SMB4ACL_T *theacl, uint16_t controlflags); > >+bool nfs_ace_is_inherit(SMB_ACE4PROP_T *ace); >+ > NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, > const struct smbacl4_vfs_params *pparams, > uint32_t security_info, >-- >2.17.1 > > >From d5965e3a43f097a04d6ef14467f31b0c1d05a3b9 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 13:20:44 -0700 >Subject: [PATCH 055/376] nfs4_acls: Add missing braces in smbacl4_win2nfs4 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit ba73d2363d93a376ba4947963c9de45a7e683f02) >--- > source3/modules/nfs4_acls.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index bab73a5cb58..11cb80e9300 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -905,12 +905,14 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > > if (pparams->acedup!=e_dontcare) { > if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl, >- &ace_v4, &addNewACE, i)) >+ &ace_v4, &addNewACE, i)) { > return NULL; >+ } > } > >- if (addNewACE) >+ if (addNewACE) { > smb_add_ace4(theacl, &ace_v4); >+ } > } > > if (pparams->mode==e_simple) { >-- >2.17.1 > > >From 428579d3fde2241a6280fae704dfda030397ff9c Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Mon, 15 Jul 2019 14:43:01 -0700 >Subject: [PATCH 056/376] nfs4_acls: Remove i argument from > smbacl4_MergeIgnoreReject > >This is only used for logging of a rejected ACL, but does not provide >additional useful information. Remove it to simplify the function a bit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 44790721e4f2c6ee6f46de7ac88123ce1a9f6e39) >--- > source3/modules/nfs4_acls.c | 15 ++++++--------- > 1 file changed, 6 insertions(+), 9 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 11cb80e9300..2317e0bc8b1 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -765,13 +765,10 @@ static bool smbacl4_fill_ace4( > return true; /* OK */ > } > >-static int smbacl4_MergeIgnoreReject( >- enum smbacl4_acedup_enum acedup, >- struct SMB4ACL_T *theacl, /* may modify it */ >- SMB_ACE4PROP_T *ace, /* the "new" ACE */ >- bool *paddNewACE, >- int i >-) >+static int smbacl4_MergeIgnoreReject(enum smbacl4_acedup_enum acedup, >+ struct SMB4ACL_T *theacl, >+ SMB_ACE4PROP_T *ace, >+ bool *paddNewACE) > { > int result = 0; > SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace); >@@ -788,7 +785,7 @@ static int smbacl4_MergeIgnoreReject( > *paddNewACE = false; > break; > case e_reject: /* do an error */ >- DEBUG(8, ("ACL rejected by duplicate nt ace#%d\n", i)); >+ DBG_INFO("ACL rejected by duplicate nt ace.\n"); > errno = EINVAL; /* SHOULD be set on any _real_ error */ > result = -1; > break; >@@ -905,7 +902,7 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > > if (pparams->acedup!=e_dontcare) { > if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl, >- &ace_v4, &addNewACE, i)) { >+ &ace_v4, &addNewACE)) { > return NULL; > } > } >-- >2.17.1 > > >From d806dba002c7ebe50e6b74fe2d43daadd0bbf05f Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 16 Jul 2019 15:20:25 -0700 >Subject: [PATCH 057/376] nfs4_acls: Move smbacl4_MergeIgnoreReject function > >This static function will be called earlier in later patches. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 3499d97463110f042415d917160bc2743805a544) >--- > source3/modules/nfs4_acls.c | 61 ++++++++++++++++++------------------- > 1 file changed, 30 insertions(+), 31 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 2317e0bc8b1..cb407c6e032 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -654,6 +654,36 @@ static SMB_ACE4PROP_T *smbacl4_find_equal_special( > return NULL; > } > >+static int smbacl4_MergeIgnoreReject(enum smbacl4_acedup_enum acedup, >+ struct SMB4ACL_T *theacl, >+ SMB_ACE4PROP_T *ace, >+ bool *paddNewACE) >+{ >+ int result = 0; >+ SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace); >+ if (ace4found) >+ { >+ switch(acedup) >+ { >+ case e_merge: /* "merge" flags */ >+ *paddNewACE = false; >+ ace4found->aceFlags |= ace->aceFlags; >+ ace4found->aceMask |= ace->aceMask; >+ break; >+ case e_ignore: /* leave out this record */ >+ *paddNewACE = false; >+ break; >+ case e_reject: /* do an error */ >+ DBG_INFO("ACL rejected by duplicate nt ace.\n"); >+ errno = EINVAL; /* SHOULD be set on any _real_ error */ >+ result = -1; >+ break; >+ default: >+ break; >+ } >+ } >+ return result; >+} > > static bool smbacl4_fill_ace4( > bool is_directory, >@@ -765,37 +795,6 @@ static bool smbacl4_fill_ace4( > return true; /* OK */ > } > >-static int smbacl4_MergeIgnoreReject(enum smbacl4_acedup_enum acedup, >- struct SMB4ACL_T *theacl, >- SMB_ACE4PROP_T *ace, >- bool *paddNewACE) >-{ >- int result = 0; >- SMB_ACE4PROP_T *ace4found = smbacl4_find_equal_special(theacl, ace); >- if (ace4found) >- { >- switch(acedup) >- { >- case e_merge: /* "merge" flags */ >- *paddNewACE = false; >- ace4found->aceFlags |= ace->aceFlags; >- ace4found->aceMask |= ace->aceMask; >- break; >- case e_ignore: /* leave out this record */ >- *paddNewACE = false; >- break; >- case e_reject: /* do an error */ >- DBG_INFO("ACL rejected by duplicate nt ace.\n"); >- errno = EINVAL; /* SHOULD be set on any _real_ error */ >- result = -1; >- break; >- default: >- break; >- } >- } >- return result; >-} >- > static int smbacl4_substitute_special( > struct SMB4ACL_T *acl, > uid_t ownerUID, >-- >2.17.1 > > >From 693aa2dbfc84631be913a364dad57a12dae3c5ba Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 16 Jul 2019 15:30:36 -0700 >Subject: [PATCH 058/376] nfs4_acls: Move adding of NFS4 ACE to ACL to > smbacl4_fill_ace4 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit abb58b17599bd3f9a06037e208dcc5033c7fdd8b) >--- > source3/modules/nfs4_acls.c | 68 +++++++++++++++++++++---------------- > 1 file changed, 39 insertions(+), 29 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index cb407c6e032..bab4dd0fd64 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -685,16 +685,41 @@ static int smbacl4_MergeIgnoreReject(enum smbacl4_acedup_enum acedup, > return result; > } > >-static bool smbacl4_fill_ace4( >+static int nfs4_acl_add_ace(enum smbacl4_acedup_enum acedup, >+ struct SMB4ACL_T *nfs4_acl, >+ SMB_ACE4PROP_T *nfs4_ace) >+{ >+ bool add_ace = true; >+ >+ if (acedup != e_dontcare) { >+ int ret; >+ >+ ret = smbacl4_MergeIgnoreReject(acedup, nfs4_acl, >+ nfs4_ace, &add_ace); >+ if (ret == -1) { >+ return -1; >+ } >+ } >+ >+ if (add_ace) { >+ smb_add_ace4(nfs4_acl, nfs4_ace); >+ } >+ >+ return 0; >+} >+ >+static int smbacl4_fill_ace4( > bool is_directory, > const struct smbacl4_vfs_params *params, > uid_t ownerUID, > gid_t ownerGID, > const struct security_ace *ace_nt, /* input */ >- SMB_ACE4PROP_T *ace_v4 /* output */ >+ struct SMB4ACL_T *nfs4_acl > ) > { > struct dom_sid_buf buf; >+ SMB_ACE4PROP_T nfs4_ace = { 0 }; >+ SMB_ACE4PROP_T *ace_v4 = &nfs4_ace; > > DEBUG(10, ("got ace for %s\n", > dom_sid_str_buf(&ace_nt->trustee, &buf))); >@@ -742,7 +767,7 @@ static bool smbacl4_fill_ace4( > ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; > if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) > && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { >- return false; >+ return 0; > } > } else if (params->mode!=e_special && > dom_sid_equal(&ace_nt->trustee, >@@ -754,7 +779,7 @@ static bool smbacl4_fill_ace4( > ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; > if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) > && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { >- return false; >+ return 0; > } > } else { > struct unixid unixid; >@@ -764,12 +789,12 @@ static bool smbacl4_fill_ace4( > if (!ok) { > DBG_WARNING("Could not convert %s to uid or gid.\n", > dom_sid_str_buf(&ace_nt->trustee, &buf)); >- return false; >+ return 0; > } > > if (dom_sid_compare_domain(&ace_nt->trustee, > &global_sid_Unix_NFS) == 0) { >- return false; >+ return 0; > } > > switch (unixid.type) { >@@ -788,11 +813,11 @@ static bool smbacl4_fill_ace4( > default: > DBG_WARNING("Could not convert %s to uid or gid.\n", > dom_sid_str_buf(&ace_nt->trustee, &buf)); >- return false; >+ return 0; > } > } > >- return true; /* OK */ >+ return nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace); > } > > static int smbacl4_substitute_special( >@@ -886,28 +911,13 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > return NULL; > > for(i=0; i<dacl->num_aces; i++) { >- SMB_ACE4PROP_T ace_v4; >- bool addNewACE = true; >- >- if (!smbacl4_fill_ace4(is_directory, pparams, >- ownerUID, ownerGID, >- dacl->aces + i, &ace_v4)) { >- struct dom_sid_buf buf; >- DEBUG(3, ("Could not fill ace for file, SID %s\n", >- dom_sid_str_buf(&((dacl->aces+i)->trustee), >- &buf))); >- continue; >- } >- >- if (pparams->acedup!=e_dontcare) { >- if (smbacl4_MergeIgnoreReject(pparams->acedup, theacl, >- &ace_v4, &addNewACE)) { >- return NULL; >- } >- } >+ int ret; > >- if (addNewACE) { >- smb_add_ace4(theacl, &ace_v4); >+ ret = smbacl4_fill_ace4(is_directory, pparams, >+ ownerUID, ownerGID, >+ dacl->aces + i, theacl); >+ if (ret == -1) { >+ return NULL; > } > } > >-- >2.17.1 > > >From b3aad3426a87d41e0fc51129a9ef2d22a4e86ab3 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 16 Jul 2019 15:50:36 -0700 >Subject: [PATCH 059/376] nfs4_acls: Remove redundant logging from > smbacl4_fill_ace4 > >Logging flags in case they do not match seems unnecessary. Other log >messages should show the flags as well. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 7ab0003ffc098247c3ee3962d7061f2af5a2d00e) >--- > source3/modules/nfs4_acls.c | 8 -------- > 1 file changed, 8 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index bab4dd0fd64..25bcc770095 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -746,14 +746,6 @@ static int smbacl4_fill_ace4( > > se_map_generic(&ace_v4->aceMask, &file_generic_mapping); > >- if (ace_v4->aceFlags!=ace_nt->flags) >- DEBUG(9, ("ace_v4->aceFlags(0x%x)!=ace_nt->flags(0x%x)\n", >- ace_v4->aceFlags, ace_nt->flags)); >- >- if (ace_v4->aceMask!=ace_nt->access_mask) >- DEBUG(9, ("ace_v4->aceMask(0x%x)!=ace_nt->access_mask(0x%x)\n", >- ace_v4->aceMask, ace_nt->access_mask)); >- > if (dom_sid_equal(&ace_nt->trustee, &global_sid_World)) { > ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE; > ace_v4->flags |= SMB_ACE4_ID_SPECIAL; >-- >2.17.1 > > >From 01e913caf03078b06592f6b66b737223896b4385 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 16 Jul 2019 15:56:12 -0700 >Subject: [PATCH 060/376] nfs4_acls: Remove redundant pointer variable > >The previous patch introduced a pointer to a local variable to reduce >the amount of lines changed. Remove that pointer and adjust all usage >accordingly. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit aa4644193635d846c2e08e8c1e7b512e8009c2ef) >--- > source3/modules/nfs4_acls.c | 56 +++++++++++++++++-------------------- > 1 file changed, 26 insertions(+), 30 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 25bcc770095..d169377295a 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -719,58 +719,54 @@ static int smbacl4_fill_ace4( > { > struct dom_sid_buf buf; > SMB_ACE4PROP_T nfs4_ace = { 0 }; >- SMB_ACE4PROP_T *ace_v4 = &nfs4_ace; > > DEBUG(10, ("got ace for %s\n", > dom_sid_str_buf(&ace_nt->trustee, &buf))); > >- ZERO_STRUCTP(ace_v4); >- > /* only ACCESS|DENY supported right now */ >- ace_v4->aceType = ace_nt->type; >+ nfs4_ace.aceType = ace_nt->type; > >- ace_v4->aceFlags = map_windows_ace_flags_to_nfs4_ace_flags( >- ace_nt->flags); >+ nfs4_ace.aceFlags = >+ map_windows_ace_flags_to_nfs4_ace_flags(ace_nt->flags); > > /* remove inheritance flags on files */ > if (!is_directory) { > DEBUG(10, ("Removing inheritance flags from a file\n")); >- ace_v4->aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE| >- SMB_ACE4_DIRECTORY_INHERIT_ACE| >- SMB_ACE4_NO_PROPAGATE_INHERIT_ACE| >- SMB_ACE4_INHERIT_ONLY_ACE); >+ nfs4_ace.aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE| >+ SMB_ACE4_DIRECTORY_INHERIT_ACE| >+ SMB_ACE4_NO_PROPAGATE_INHERIT_ACE| >+ SMB_ACE4_INHERIT_ONLY_ACE); > } > >- ace_v4->aceMask = ace_nt->access_mask & >- (SEC_STD_ALL | SEC_FILE_ALL); >+ nfs4_ace.aceMask = ace_nt->access_mask & (SEC_STD_ALL | SEC_FILE_ALL); > >- se_map_generic(&ace_v4->aceMask, &file_generic_mapping); >+ se_map_generic(&nfs4_ace.aceMask, &file_generic_mapping); > > if (dom_sid_equal(&ace_nt->trustee, &global_sid_World)) { >- ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE; >- ace_v4->flags |= SMB_ACE4_ID_SPECIAL; >+ nfs4_ace.who.special_id = SMB_ACE4_WHO_EVERYONE; >+ nfs4_ace.flags |= SMB_ACE4_ID_SPECIAL; > } else if (params->mode!=e_special && > dom_sid_equal(&ace_nt->trustee, > &global_sid_Creator_Owner)) { > DEBUG(10, ("Map creator owner\n")); >- ace_v4->who.special_id = SMB_ACE4_WHO_OWNER; >- ace_v4->flags |= SMB_ACE4_ID_SPECIAL; >+ nfs4_ace.who.special_id = SMB_ACE4_WHO_OWNER; >+ nfs4_ace.flags |= SMB_ACE4_ID_SPECIAL; > /* A non inheriting creator owner entry has no effect. */ >- ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; >- if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) >- && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { >+ nfs4_ace.aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; >+ if (!(nfs4_ace.aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) >+ && !(nfs4_ace.aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { > return 0; > } > } else if (params->mode!=e_special && > dom_sid_equal(&ace_nt->trustee, > &global_sid_Creator_Group)) { > DEBUG(10, ("Map creator owner group\n")); >- ace_v4->who.special_id = SMB_ACE4_WHO_GROUP; >- ace_v4->flags |= SMB_ACE4_ID_SPECIAL; >+ nfs4_ace.who.special_id = SMB_ACE4_WHO_GROUP; >+ nfs4_ace.flags |= SMB_ACE4_ID_SPECIAL; > /* A non inheriting creator group entry has no effect. */ >- ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; >- if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) >- && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { >+ nfs4_ace.aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; >+ if (!(nfs4_ace.aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE) >+ && !(nfs4_ace.aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) { > return 0; > } > } else { >@@ -791,15 +787,15 @@ static int smbacl4_fill_ace4( > > switch (unixid.type) { > case ID_TYPE_BOTH: >- ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >- ace_v4->who.gid = unixid.id; >+ nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >+ nfs4_ace.who.gid = unixid.id; > break; > case ID_TYPE_GID: >- ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >- ace_v4->who.gid = unixid.id; >+ nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >+ nfs4_ace.who.gid = unixid.id; > break; > case ID_TYPE_UID: >- ace_v4->who.uid = unixid.id; >+ nfs4_ace.who.uid = unixid.id; > break; > case ID_TYPE_NOT_SPECIFIED: > default: >-- >2.17.1 > > >From 8ac9c1f75f3f01370c9dba5d570f95c48e2029b4 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 17 Jul 2019 10:49:47 -0700 >Subject: [PATCH 061/376] nfs4_acls: Add additional owner entry when mapping to > NFS4 ACL with IDMAP_TYPE_BOTH > >With IDMAP_TYPE_BOTH, all entries have to be mapped to group entries. >In order to have the file system reflect the owner permissions in the >POSIX modebits, create a second entry for the user. This will be mapped >to the "special owner" entry. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit b796119e2df38d1935064556934dd10da6f3d339) >--- > source3/modules/nfs4_acls.c | 37 +++++++++++++++++++++++++++++- > source3/modules/test_nfs4_acls.c | 39 +++++++++++++++++++++++++++----- > 2 files changed, 69 insertions(+), 7 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index d169377295a..70d725eb937 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -719,6 +719,9 @@ static int smbacl4_fill_ace4( > { > struct dom_sid_buf buf; > SMB_ACE4PROP_T nfs4_ace = { 0 }; >+ SMB_ACE4PROP_T nfs4_ace_2 = { 0 }; >+ bool add_ace2 = false; >+ int ret; > > DEBUG(10, ("got ace for %s\n", > dom_sid_str_buf(&ace_nt->trustee, &buf))); >@@ -789,6 +792,29 @@ static int smbacl4_fill_ace4( > case ID_TYPE_BOTH: > nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; > nfs4_ace.who.gid = unixid.id; >+ >+ if (ownerUID == unixid.id && >+ !nfs_ace_is_inherit(&nfs4_ace)) >+ { >+ /* >+ * IDMAP_TYPE_BOTH for owner. Add >+ * additional user entry, which can be >+ * mapped to special:owner to reflect >+ * the permissions in the modebits. >+ * >+ * This only applies to non-inheriting >+ * entries as only these are replaced >+ * with SPECIAL_OWNER in nfs4:mode=simple. >+ */ >+ nfs4_ace_2 = (SMB_ACE4PROP_T) { >+ .who.uid = unixid.id, >+ .aceFlags = (nfs4_ace.aceFlags & >+ ~SMB_ACE4_IDENTIFIER_GROUP), >+ .aceMask = nfs4_ace.aceMask, >+ .aceType = nfs4_ace.aceType, >+ }; >+ add_ace2 = true; >+ } > break; > case ID_TYPE_GID: > nfs4_ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; >@@ -805,7 +831,16 @@ static int smbacl4_fill_ace4( > } > } > >- return nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace); >+ ret = nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace); >+ if (ret != 0) { >+ return -1; >+ } >+ >+ if (!add_ace2) { >+ return 0; >+ } >+ >+ return nfs4_acl_add_ace(params->acedup, nfs4_acl, &nfs4_ace_2); > } > > static int smbacl4_substitute_special( >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index d7152a0737a..170a397579a 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1671,6 +1671,7 @@ struct dacl_to_nfs4_idmap_both { > uint32_t nfs4_flags; > uint32_t nfs4_ace_flags; > uint32_t nfs4_id; >+ int num_nfs4_aces; > }; > > /* >@@ -1684,13 +1685,17 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) > > struct dacl_to_nfs4_idmap_both dacl_to_nfs4_idmap_both[] = { > { &sids[2], 0, >- SMB_ACE4_ID_SPECIAL, SMB_ACE4_IDENTIFIER_GROUP, SMB_ACE4_WHO_GROUP }, >+ SMB_ACE4_ID_SPECIAL, SMB_ACE4_IDENTIFIER_GROUP, SMB_ACE4_WHO_GROUP, >+ 2 }, > { &sids[2], SEC_ACE_FLAG_OBJECT_INHERIT, >- 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002 }, >+ 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1002, >+ 1 }, > { &sids[6], 0, >- 0, SMB_ACE4_IDENTIFIER_GROUP, 1005 }, >+ 0, SMB_ACE4_IDENTIFIER_GROUP, 1005, >+ 1 }, > { &sids[6], SEC_ACE_FLAG_OBJECT_INHERIT, >- 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1005 }, >+ 0, SMB_ACE4_IDENTIFIER_GROUP|SMB_ACE4_FILE_INHERIT_ACE, 1005, >+ 1 }, > }; > > for (i = 0; i < ARRAY_SIZE(dacl_to_nfs4_idmap_both); i++) { >@@ -1720,11 +1725,11 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) > assert_non_null(nfs4_acl); > assert_int_equal(smbacl4_get_controlflags(nfs4_acl), > SEC_DESC_SELF_RELATIVE); >- assert_int_equal(smb_get_naces(nfs4_acl), 1); >+ assert_int_equal(smb_get_naces(nfs4_acl), >+ dacl_to_nfs4_idmap_both[i].num_nfs4_aces); > > nfs4_ace_container = smb_first_ace4(nfs4_acl); > assert_non_null(nfs4_ace_container); >- assert_null(smb_next_ace4(nfs4_ace_container)); > > nfs4_ace = smb_get_ace4(nfs4_ace_container); > assert_int_equal(nfs4_ace->flags, >@@ -1744,6 +1749,28 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) > assert_int_equal(nfs4_ace->aceType, > SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE); > assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ >+ if (dacl_to_nfs4_idmap_both[i].num_nfs4_aces == 2) { >+ nfs4_ace_container = smb_next_ace4(nfs4_ace_container); >+ assert_non_null(nfs4_ace_container); >+ >+ nfs4_ace = smb_get_ace4(nfs4_ace_container); >+ assert_int_equal(nfs4_ace->flags, >+ dacl_to_nfs4_idmap_both[i].nfs4_flags); >+ assert_int_equal(nfs4_ace->aceFlags, >+ dacl_to_nfs4_idmap_both[i].nfs4_ace_flags & >+ ~SMB_ACE4_IDENTIFIER_GROUP); >+ if (nfs4_ace->flags & SMB_ACE4_ID_SPECIAL) { >+ assert_int_equal(nfs4_ace->who.special_id, >+ SMB_ACE4_WHO_OWNER); >+ } else { >+ assert_int_equal(nfs4_ace->who.uid, >+ dacl_to_nfs4_idmap_both[i].nfs4_id); >+ } >+ assert_int_equal(nfs4_ace->aceType, >+ SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE); >+ assert_int_equal(nfs4_ace->aceMask, SMB_ACE4_READ_DATA); >+ } > } > > TALLOC_FREE(frame); >-- >2.17.1 > > >From 7d40b00bac82d8cd185850aa1b8a13c5f79848d7 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Thu, 18 Jul 2019 11:49:29 -0700 >Subject: [PATCH 062/376] nfs4_acls: Rename smbacl4_fill_ace4 function > >As this function now maps the ACE and also adds it to the NFSv4 ACE, >change the name to better describe its behavior. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 169812943de23cf2752289c63331d786b0b063bd) >--- > source3/modules/nfs4_acls.c | 20 +++++++++----------- > 1 file changed, 9 insertions(+), 11 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 70d725eb937..663fcba67aa 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -708,14 +708,12 @@ static int nfs4_acl_add_ace(enum smbacl4_acedup_enum acedup, > return 0; > } > >-static int smbacl4_fill_ace4( >- bool is_directory, >- const struct smbacl4_vfs_params *params, >- uid_t ownerUID, >- gid_t ownerGID, >- const struct security_ace *ace_nt, /* input */ >- struct SMB4ACL_T *nfs4_acl >-) >+static int nfs4_acl_add_sec_ace(bool is_directory, >+ const struct smbacl4_vfs_params *params, >+ uid_t ownerUID, >+ gid_t ownerGID, >+ const struct security_ace *ace_nt, >+ struct SMB4ACL_T *nfs4_acl) > { > struct dom_sid_buf buf; > SMB_ACE4PROP_T nfs4_ace = { 0 }; >@@ -936,9 +934,9 @@ static struct SMB4ACL_T *smbacl4_win2nfs4( > for(i=0; i<dacl->num_aces; i++) { > int ret; > >- ret = smbacl4_fill_ace4(is_directory, pparams, >- ownerUID, ownerGID, >- dacl->aces + i, theacl); >+ ret = nfs4_acl_add_sec_ace(is_directory, pparams, >+ ownerUID, ownerGID, >+ dacl->aces + i, theacl); > if (ret == -1) { > return NULL; > } >-- >2.17.1 > > >From 78d426fb0d4f9332e9c0a084993b5f2f5e0cdc40 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 2 Jul 2019 15:08:11 -0700 >Subject: [PATCH 063/376] nfs4_acls: Remove duplicate entries when mapping from > NFS4 ACL to DACL > >The previous patch added an additional entry for IDMAP_TYPE_BOTH. When >mapping back to a DACL, there should be no additional entry. Add a loop >that will check and remove entries that are exact duplicates. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 9c88602128592ddad537bf70cbe3c51f0b2cebe5) >--- > source3/modules/nfs4_acls.c | 31 +++++++++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 663fcba67aa..74b66a2c392 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -297,6 +297,35 @@ static int smbacl4_fGetFileOwner(files_struct *fsp, SMB_STRUCT_STAT *psbuf) > return 0; > } > >+static void check_for_duplicate_sec_ace(struct security_ace *nt_ace_list, >+ int *good_aces) >+{ >+ struct security_ace *last = NULL; >+ int i; >+ >+ if (*good_aces < 2) { >+ return; >+ } >+ >+ last = &nt_ace_list[(*good_aces) - 1]; >+ >+ for (i = 0; i < (*good_aces) - 1; i++) { >+ struct security_ace *cur = &nt_ace_list[i]; >+ >+ if (cur->type == last->type && >+ cur->flags == last->flags && >+ cur->access_mask == last->access_mask && >+ dom_sid_equal(&cur->trustee, &last->trustee)) >+ { >+ struct dom_sid_buf sid_buf; >+ >+ DBG_INFO("Removing duplicate entry for SID %s.\n", >+ dom_sid_str_buf(&last->trustee, &sid_buf)); >+ (*good_aces)--; >+ } >+ } >+} >+ > static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, > const struct smbacl4_vfs_params *params, > struct SMB4ACL_T *acl, /* in */ >@@ -438,6 +467,8 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, > ace->aceType, mask, > win_ace_flags); > } >+ >+ check_for_duplicate_sec_ace(nt_ace_list, &good_aces); > } > > nt_ace_list = talloc_realloc(mem_ctx, nt_ace_list, struct security_ace, >-- >2.17.1 > > >From 77052fbc65a375dc5a3dda4ac9d212b808ca802f Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 10 Jul 2019 13:14:32 -0700 >Subject: [PATCH 064/376] nfs4_acls: Add test for merging duplicates when > mapping from NFS4 ACL to DACL > >The previous patch introduced merging of duplicates on the mapping path >from NFS4 ACL entries to DACL entries. Add a testcase to verify the >expected behavior of this codepath. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 1a137a2f20c2f159c5feaef230a2b85bb9fb23b5) >--- > source3/modules/test_nfs4_acls.c | 79 ++++++++++++++++++++++++++++++++ > 1 file changed, 79 insertions(+) > >diff --git a/source3/modules/test_nfs4_acls.c b/source3/modules/test_nfs4_acls.c >index 170a397579a..0b23bd1d02e 100644 >--- a/source3/modules/test_nfs4_acls.c >+++ b/source3/modules/test_nfs4_acls.c >@@ -1776,6 +1776,84 @@ static void test_dacl_to_nfs4_idmap_type_both(void **state) > TALLOC_FREE(frame); > } > >+static void test_nfs4_to_dacl_remove_duplicate(void **state) >+{ >+ >+ struct dom_sid *sids = *state; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct SMB4ACL_T *nfs4_acl; >+ SMB_ACE4PROP_T nfs4_ace; >+ struct security_ace *dacl_aces; >+ int good_aces; >+ struct smbacl4_vfs_params params = { >+ .mode = e_simple, >+ .do_chown = true, >+ .acedup = e_dontcare, >+ .map_full_control = true, >+ }; >+ >+ nfs4_acl = smb_create_smb4acl(frame); >+ assert_non_null(nfs4_acl); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.uid = 1002, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_INHERITED_ACE, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.gid = 1002, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_INHERITED_ACE, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.gid = 1002, >+ .aceType = SMB_ACE4_ACCESS_DENIED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_INHERITED_ACE, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ nfs4_ace = (SMB_ACE4PROP_T) { >+ .flags = 0, >+ .who.gid = 1002, >+ .aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE, >+ .aceFlags = SMB_ACE4_IDENTIFIER_GROUP| >+ SMB_ACE4_INHERITED_ACE, >+ .aceMask = SMB_ACE4_WRITE_DATA, >+ }; >+ assert_non_null(smb_add_ace4(nfs4_acl, &nfs4_ace)); >+ >+ assert_true(smbacl4_nfs42win(frame, ¶ms, nfs4_acl, >+ &sids[0], &sids[1], true, >+ &dacl_aces, &good_aces)); >+ >+ assert_int_equal(good_aces, 2); >+ assert_non_null(dacl_aces); >+ >+ assert_int_equal(dacl_aces[0].type, SEC_ACE_TYPE_ACCESS_ALLOWED); >+ assert_int_equal(dacl_aces[0].flags, SEC_ACE_FLAG_INHERITED_ACE); >+ assert_int_equal(dacl_aces[0].access_mask, SEC_FILE_WRITE_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[0].trustee, &sids[2])); >+ >+ assert_int_equal(dacl_aces[1].type, SEC_ACE_TYPE_ACCESS_DENIED); >+ assert_int_equal(dacl_aces[1].flags, SEC_ACE_FLAG_INHERITED_ACE); >+ assert_int_equal(dacl_aces[1].access_mask, SEC_FILE_WRITE_DATA); >+ assert_true(dom_sid_equal(&dacl_aces[1].trustee, &sids[2])); >+ >+ TALLOC_FREE(frame); >+} >+ > int main(int argc, char **argv) > { > const struct CMUnitTest tests[] = { >@@ -1799,6 +1877,7 @@ int main(int argc, char **argv) > cmocka_unit_test(test_nfs4_to_dacl_config_special), > cmocka_unit_test(test_nfs4_to_dacl_idmap_type_both), > cmocka_unit_test(test_dacl_to_nfs4_idmap_type_both), >+ cmocka_unit_test(test_nfs4_to_dacl_remove_duplicate), > }; > > cmocka_set_message_output(CM_OUTPUT_SUBUNIT); >-- >2.17.1 > > >From d186689038c5f807b092f63d7f89fd6b6dd95241 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 17 Jul 2019 15:29:06 -0700 >Subject: [PATCH 065/376] nfs4_acls: Use correct owner information for ACL > after owner change > >After a chown, the cached stat data is obviously no longer valid. The >code in smb_set_nt_acl_nfs4 checked the file correctly, but did only use >a local buffer for the stat data. So later checks of the stat buffer >under the fsp->fsp_name->st would still see the old information. > >Fix this by removing the local stat buffer and always update the one >under fsp->fsp_name->st. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 86f7af84f04b06ed96b30f936ace92aa0937be06) >--- > source3/modules/nfs4_acls.c | 36 ++++++++++++++++++++++-------------- > 1 file changed, 22 insertions(+), 14 deletions(-) > >diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c >index 74b66a2c392..eb76696948b 100644 >--- a/source3/modules/nfs4_acls.c >+++ b/source3/modules/nfs4_acls.c >@@ -994,11 +994,11 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > struct SMB4ACL_T *theacl = NULL; > bool result, is_directory; > >- SMB_STRUCT_STAT sbuf; > bool set_acl_as_root = false; > uid_t newUID = (uid_t)-1; > gid_t newGID = (gid_t)-1; > int saved_errno; >+ NTSTATUS status; > TALLOC_CTX *frame = talloc_stackframe(); > > DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp_str_dbg(fsp))); >@@ -1022,25 +1022,29 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > pparams = ¶ms; > } > >- if (smbacl4_fGetFileOwner(fsp, &sbuf)) { >+ status = vfs_stat_fsp(fsp); >+ if (!NT_STATUS_IS_OK(status)) { > TALLOC_FREE(frame); >- return map_nt_error_from_unix(errno); >+ return status; > } > >- is_directory = S_ISDIR(sbuf.st_ex_mode); >+ is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode); > > if (pparams->do_chown) { > /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */ >- NTSTATUS status = unpack_nt_owners(fsp->conn, &newUID, &newGID, >- security_info_sent, psd); >+ >+ uid_t old_uid = fsp->fsp_name->st.st_ex_uid; >+ uid_t old_gid = fsp->fsp_name->st.st_ex_uid; >+ status = unpack_nt_owners(fsp->conn, &newUID, &newGID, >+ security_info_sent, psd); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(8, ("unpack_nt_owners failed")); > TALLOC_FREE(frame); > return status; > } >- if (((newUID != (uid_t)-1) && (sbuf.st_ex_uid != newUID)) || >- ((newGID != (gid_t)-1) && (sbuf.st_ex_gid != newGID))) { >- >+ if (((newUID != (uid_t)-1) && (old_uid != newUID)) || >+ ((newGID != (gid_t)-1) && (old_gid != newGID))) >+ { > status = try_chown(fsp, newUID, newGID); > if (!NT_STATUS_IS_OK(status)) { > DEBUG(3,("chown %s, %u, %u failed. Error = " >@@ -1055,11 +1059,14 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > DEBUG(10,("chown %s, %u, %u succeeded.\n", > fsp_str_dbg(fsp), (unsigned int)newUID, > (unsigned int)newGID)); >- if (smbacl4_GetFileOwner(fsp->conn, >- fsp->fsp_name, >- &sbuf)){ >+ >+ /* >+ * Owner change, need to update stat info. >+ */ >+ status = vfs_stat_fsp(fsp); >+ if (!NT_STATUS_IS_OK(status)) { > TALLOC_FREE(frame); >- return map_nt_error_from_unix(errno); >+ return status; > } > > /* If we successfully chowned, we know we must >@@ -1077,7 +1084,8 @@ NTSTATUS smb_set_nt_acl_nfs4(vfs_handle_struct *handle, files_struct *fsp, > } > > theacl = smbacl4_win2nfs4(frame, is_directory, psd->dacl, pparams, >- sbuf.st_ex_uid, sbuf.st_ex_gid); >+ fsp->fsp_name->st.st_ex_uid, >+ fsp->fsp_name->st.st_ex_gid); > if (!theacl) { > TALLOC_FREE(frame); > return map_nt_error_from_unix(errno); >-- >2.17.1 > > >From 7c90ecdb15cc6d572a37c2d435b6c7d86559d944 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 9 Jul 2019 12:04:35 -0700 >Subject: [PATCH 066/376] vfs_gpfs: Remove merge_writeappend parameter > >All supported GPFS versions now support setting WRITE and APPEND in the >ACLs independently. Remove this now unused parameter to simplify the >code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 0aca678fcf1788a76cf0ff11399211c795aa7d2f) >--- > source3/modules/vfs_gpfs.c | 23 ----------------------- > 1 file changed, 23 deletions(-) > >diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c >index 4b963edab11..72c06a6dcb1 100644 >--- a/source3/modules/vfs_gpfs.c >+++ b/source3/modules/vfs_gpfs.c >@@ -708,29 +708,6 @@ static struct gpfs_acl *vfs_gpfs_smbacl2gpfsacl(TALLOC_CTX *mem_ctx, > gace->aceType = aceprop->aceType; > gace->aceFlags = aceprop->aceFlags; > gace->aceMask = aceprop->aceMask; >- >- /* >- * GPFS can't distinguish between WRITE and APPEND on >- * files, so one being set without the other is an >- * error. Sorry for the many ()'s :-) >- */ >- >- if (!fsp->is_directory >- && >- ((((gace->aceMask & ACE4_MASK_WRITE) == 0) >- && ((gace->aceMask & ACE4_MASK_APPEND) != 0)) >- || >- (((gace->aceMask & ACE4_MASK_WRITE) != 0) >- && ((gace->aceMask & ACE4_MASK_APPEND) == 0))) >- && >- lp_parm_bool(fsp->conn->params->service, "gpfs", >- "merge_writeappend", True)) { >- DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains " >- "WRITE^APPEND, setting WRITE|APPEND\n", >- fsp_str_dbg(fsp))); >- gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND; >- } >- > gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0; > > if (aceprop->flags&SMB_ACE4_ID_SPECIAL) >-- >2.17.1 > > >From 90ddc22ea5552b7d3a2c4cc7cb1b75e3ef1e52f2 Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 10 Jul 2019 11:06:19 -0700 >Subject: [PATCH 067/376] docs: Remove gpfs:merge_writeappend from vfs_gpfs > manpage > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit 8bd79ecc37376dbaa35606f9c2777653eb3d55e3) >--- > docs-xml/manpages/vfs_gpfs.8.xml | 20 -------------------- > 1 file changed, 20 deletions(-) > >diff --git a/docs-xml/manpages/vfs_gpfs.8.xml b/docs-xml/manpages/vfs_gpfs.8.xml >index 2f3b4274e4b..fb1f5bb2237 100644 >--- a/docs-xml/manpages/vfs_gpfs.8.xml >+++ b/docs-xml/manpages/vfs_gpfs.8.xml >@@ -204,26 +204,6 @@ > </varlistentry> > <varlistentry> > >- <term>gpfs:merge_writeappend = [ yes | no ]</term> >- <listitem> >- <para> >- GPFS ACLs doesn't know about the 'APPEND' right. >- This option lets Samba map the 'APPEND' right to 'WRITE'. >- </para> >- >- <itemizedlist> >- <listitem><para> >- <command>yes(default)</command> - map 'APPEND' to 'WRITE'. >- </para></listitem> >- <listitem><para> >- <command>no</command> - do not map 'APPEND' to 'WRITE'. >- </para></listitem> >- </itemizedlist> >- </listitem> >- >- </varlistentry> >- <varlistentry> >- > <term>gpfs:acl = [ yes | no ]</term> > <listitem> > <para> >-- >2.17.1 > > >From 39495b14cdd228c842666222952ad789e63977ef Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 9 Jul 2019 13:08:35 -0700 >Subject: [PATCH 068/376] vfs_gpfs: Move mapping from generic NFSv ACL to GPFS > ACL to separate function > >This is not functional change. It cleans up the code a bit and makes >expanding this codepath in a later patch easier. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit fbf3a090a9ec94262b2924461cc1d6336af9919c) >--- > source3/modules/vfs_gpfs.c | 69 ++++++++++++++++++++++---------------- > 1 file changed, 41 insertions(+), 28 deletions(-) > >diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c >index 72c06a6dcb1..d0dc1ddb173 100644 >--- a/source3/modules/vfs_gpfs.c >+++ b/source3/modules/vfs_gpfs.c >@@ -672,6 +672,43 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, > return map_nt_error_from_unix(errno); > } > >+static bool vfs_gpfs_nfs4_ace_to_gpfs_ace(SMB_ACE4PROP_T *nfs4_ace, >+ struct gpfs_ace_v4 *gace) >+{ >+ gace->aceType = nfs4_ace->aceType; >+ gace->aceFlags = nfs4_ace->aceFlags; >+ gace->aceMask = nfs4_ace->aceMask; >+ >+ if (nfs4_ace->flags & SMB_ACE4_ID_SPECIAL) { >+ switch(nfs4_ace->who.special_id) { >+ case SMB_ACE4_WHO_EVERYONE: >+ gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >+ gace->aceWho = ACE4_SPECIAL_EVERYONE; >+ break; >+ case SMB_ACE4_WHO_OWNER: >+ gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >+ gace->aceWho = ACE4_SPECIAL_OWNER; >+ break; >+ case SMB_ACE4_WHO_GROUP: >+ gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >+ gace->aceWho = ACE4_SPECIAL_GROUP; >+ break; >+ default: >+ DBG_WARNING("Unsupported special_id %d\n", >+ nfs4_ace->who.special_id); >+ return false; >+ } >+ >+ return true; >+ } >+ >+ gace->aceIFlags = 0; >+ gace->aceWho = (nfs4_ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) ? >+ nfs4_ace->who.gid : nfs4_ace->who.uid; >+ >+ return true; >+} >+ > static struct gpfs_acl *vfs_gpfs_smbacl2gpfsacl(TALLOC_CTX *mem_ctx, > files_struct *fsp, > struct SMB4ACL_T *smbacl, >@@ -704,35 +741,11 @@ static struct gpfs_acl *vfs_gpfs_smbacl2gpfsacl(TALLOC_CTX *mem_ctx, > for (smbace=smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) { > struct gpfs_ace_v4 *gace = gpfs_ace_ptr(gacl, gacl->acl_nace); > SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace); >+ bool add_ace; > >- gace->aceType = aceprop->aceType; >- gace->aceFlags = aceprop->aceFlags; >- gace->aceMask = aceprop->aceMask; >- gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0; >- >- if (aceprop->flags&SMB_ACE4_ID_SPECIAL) >- { >- switch(aceprop->who.special_id) >- { >- case SMB_ACE4_WHO_EVERYONE: >- gace->aceWho = ACE4_SPECIAL_EVERYONE; >- break; >- case SMB_ACE4_WHO_OWNER: >- gace->aceWho = ACE4_SPECIAL_OWNER; >- break; >- case SMB_ACE4_WHO_GROUP: >- gace->aceWho = ACE4_SPECIAL_GROUP; >- break; >- default: >- DEBUG(8, ("unsupported special_id %d\n", aceprop->who.special_id)); >- continue; /* don't add it !!! */ >- } >- } else { >- /* just only for the type safety... */ >- if (aceprop->aceFlags&SMB_ACE4_IDENTIFIER_GROUP) >- gace->aceWho = aceprop->who.gid; >- else >- gace->aceWho = aceprop->who.uid; >+ add_ace = vfs_gpfs_nfs4_ace_to_gpfs_ace(aceprop, gace); >+ if (!add_ace) { >+ continue; > } > > gacl->acl_nace++; >-- >2.17.1 > > >From d18896d19988b1096849c00a80dda42a727d5c4c Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Tue, 9 Jul 2019 13:39:55 -0700 >Subject: [PATCH 069/376] vfs_gpfs: Implement special case for denying owner > access to ACL > >In GPFS, it is not possible to deny ACL or attribute access through a >SPECIAL_OWNER entry. The best that can be done is mapping this to a >named user entry, as this one can at least be stored in an ACL. The same >cannot be done for inheriting SPECIAL_OWNER entries, as these represent >CREATOR OWNER entries, and the limitation of not being able to deny >owner access to ACL or attributes remains. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14032 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >(cherry picked from commit c1770ed96fd3137f45d584ba9328333d5505e3af) >--- > source3/modules/vfs_gpfs.c | 37 +++++++++++++++++++++++++++++++++---- > 1 file changed, 33 insertions(+), 4 deletions(-) > >diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c >index d0dc1ddb173..f0d5074d36b 100644 >--- a/source3/modules/vfs_gpfs.c >+++ b/source3/modules/vfs_gpfs.c >@@ -673,7 +673,8 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, > } > > static bool vfs_gpfs_nfs4_ace_to_gpfs_ace(SMB_ACE4PROP_T *nfs4_ace, >- struct gpfs_ace_v4 *gace) >+ struct gpfs_ace_v4 *gace, >+ uid_t owner_uid) > { > gace->aceType = nfs4_ace->aceType; > gace->aceFlags = nfs4_ace->aceFlags; >@@ -686,8 +687,35 @@ static bool vfs_gpfs_nfs4_ace_to_gpfs_ace(SMB_ACE4PROP_T *nfs4_ace, > gace->aceWho = ACE4_SPECIAL_EVERYONE; > break; > case SMB_ACE4_WHO_OWNER: >- gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >- gace->aceWho = ACE4_SPECIAL_OWNER; >+ /* >+ * With GPFS it is not possible to deny ACL or >+ * attribute access to the owner. Setting an >+ * ACL with such an entry is not possible. >+ * Denying ACL or attribute access for the >+ * owner through a named ACL entry can be >+ * stored in an ACL, it is just not effective. >+ * >+ * Map this case to a named entry to allow at >+ * least setting this ACL, which will be >+ * enforced by the smbd permission check. Do >+ * not do this for an inheriting OWNER entry, >+ * as this represents a CREATOR OWNER ACE. The >+ * remaining limitation is that CREATOR OWNER >+ * cannot deny ACL or attribute access. >+ */ >+ if (!nfs_ace_is_inherit(nfs4_ace) && >+ nfs4_ace->aceType == >+ SMB_ACE4_ACCESS_DENIED_ACE_TYPE && >+ nfs4_ace->aceMask & (SMB_ACE4_READ_ATTRIBUTES| >+ SMB_ACE4_WRITE_ATTRIBUTES| >+ SMB_ACE4_READ_ACL| >+ SMB_ACE4_WRITE_ACL)) { >+ gace->aceIFlags = 0; >+ gace->aceWho = owner_uid; >+ } else { >+ gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >+ gace->aceWho = ACE4_SPECIAL_OWNER; >+ } > break; > case SMB_ACE4_WHO_GROUP: > gace->aceIFlags = ACE4_IFLAG_SPECIAL_ID; >@@ -743,7 +771,8 @@ static struct gpfs_acl *vfs_gpfs_smbacl2gpfsacl(TALLOC_CTX *mem_ctx, > SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace); > bool add_ace; > >- add_ace = vfs_gpfs_nfs4_ace_to_gpfs_ace(aceprop, gace); >+ add_ace = vfs_gpfs_nfs4_ace_to_gpfs_ace(aceprop, gace, >+ fsp->fsp_name->st.st_ex_uid); > if (!add_ace) { > continue; > } >-- >2.17.1 > > >From be508cda25d97b825fef3d605938faa3726cde44 Mon Sep 17 00:00:00 2001 >From: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Date: Mon, 22 Jul 2019 15:29:03 +1200 >Subject: [PATCH 070/376] downgradedatabase: comply with samba.tests.source > >In next commit we'll install the script, samba.tests.source picked up the >lack of a copyright message and some whitespace errors, so this patch >fixes that stuff first. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit c4aebb15001c830a46d5a6ad8ea11a6f9ea4fd04) >--- > source4/scripting/bin/sambadowngradedatabase | 26 +++++++++++++++++--- > 1 file changed, 23 insertions(+), 3 deletions(-) > >diff --git a/source4/scripting/bin/sambadowngradedatabase b/source4/scripting/bin/sambadowngradedatabase >index 9d1e2b8cc76..87a989bfd6a 100755 >--- a/source4/scripting/bin/sambadowngradedatabase >+++ b/source4/scripting/bin/sambadowngradedatabase >@@ -1,4 +1,24 @@ >-#!/usr/bin/env python3 >+#!/usr/bin/python3 >+# >+# Unix SMB/CIFS implementation. >+# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019 >+# >+# Downgrade a database from 4.11 format to 4.7 format. 4.7 Format will >+# run on any version of Samba AD, and Samba will repack/reconfigure the >+# database if necessary. >+# >+# This program is free software; you can redistribute it and/or modify >+# it under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# This program is distributed in the hope that it will be useful, >+# but WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with this program. If not, see <http://www.gnu.org/licenses/>. > from __future__ import print_function > import optparse > import sys >@@ -38,9 +58,9 @@ samdb = ldb.Ldb(url=url, > options=["modules:"]) > > partitions = samdb.search(base="@PARTITION", >- scope=ldb.SCOPE_BASE, >+ scope=ldb.SCOPE_BASE, > attrs=["backendStore", "partition"]) >- >+ > backend = str(partitions[0].get('backendStore', 'tdb')) > > if backend == "mdb": >-- >2.17.1 > > >From 7a8f68f615034c696e90f86eb1670f4b100300fc Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Mon, 29 Jul 2019 13:35:08 +1200 >Subject: [PATCH 071/376] tests: Avoid hardcoding relative filepath > >If we move the test file, the test will break. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit a8cdbe0b824f57f73eee09143148f009a9c58582) >--- > python/samba/tests/blackbox/downgradedatabase.py | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/python/samba/tests/blackbox/downgradedatabase.py b/python/samba/tests/blackbox/downgradedatabase.py >index a5e540c1354..4a8411b1f1a 100644 >--- a/python/samba/tests/blackbox/downgradedatabase.py >+++ b/python/samba/tests/blackbox/downgradedatabase.py >@@ -23,8 +23,8 @@ import shutil > from subprocess import check_output > from samba.samdb import SamDB > >-COMMAND = os.path.join(os.path.dirname(__file__), >- "../../../../../source4/scripting/bin/sambadowngradedatabase") >+COMMAND = os.path.join(os.environ.get("SRCDIR_ABS"), >+ "source4/scripting/bin/sambadowngradedatabase") > > > class DowngradeTestBase(BlackboxTestCase): >-- >2.17.1 > > >From a1b3796b5643d7d727964751efb19675d5ee42c7 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Mon, 29 Jul 2019 13:39:04 +1200 >Subject: [PATCH 072/376] downgradedatabase: rename to samba_downgrade_db > >Just so that it's slightly less of a mouthful for users. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit fdaaee8d3aac77d91642a7d75d4bcd15d4df8657) >--- > python/samba/tests/blackbox/downgradedatabase.py | 2 +- > selftest/knownfail.d/usage | 2 +- > .../bin/{sambadowngradedatabase => samba_downgrade_db} | 0 > 3 files changed, 2 insertions(+), 2 deletions(-) > rename source4/scripting/bin/{sambadowngradedatabase => samba_downgrade_db} (100%) > >diff --git a/python/samba/tests/blackbox/downgradedatabase.py b/python/samba/tests/blackbox/downgradedatabase.py >index 4a8411b1f1a..3d230609efc 100644 >--- a/python/samba/tests/blackbox/downgradedatabase.py >+++ b/python/samba/tests/blackbox/downgradedatabase.py >@@ -24,7 +24,7 @@ from subprocess import check_output > from samba.samdb import SamDB > > COMMAND = os.path.join(os.environ.get("SRCDIR_ABS"), >- "source4/scripting/bin/sambadowngradedatabase") >+ "source4/scripting/bin/samba_downgrade_db") > > > class DowngradeTestBase(BlackboxTestCase): >diff --git a/selftest/knownfail.d/usage b/selftest/knownfail.d/usage >index 23d52c0b727..0a495858e8c 100644 >--- a/selftest/knownfail.d/usage >+++ b/selftest/knownfail.d/usage >@@ -25,7 +25,7 @@ samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rebuildextendedd > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_renamedc.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_repl_cleartext_pwd_py.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rodcdns.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_sambadowngradedatabase.none. >+samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_downgrade_db.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate_.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc.none. >diff --git a/source4/scripting/bin/sambadowngradedatabase b/source4/scripting/bin/samba_downgrade_db >similarity index 100% >rename from source4/scripting/bin/sambadowngradedatabase >rename to source4/scripting/bin/samba_downgrade_db >-- >2.17.1 > > >From 309ec3b63c5d9f441bcc922e62c2f6a2c2907f62 Mon Sep 17 00:00:00 2001 >From: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Date: Mon, 22 Jul 2019 13:35:21 +1200 >Subject: [PATCH 073/376] downgradedatabase: Add man-page documentation > >A man-page is needed so that we can install this tool as part of the >Samba package. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit c89df3862b17fad9c4648b5d9c6805120d732df8) >--- > docs-xml/manpages/samba_downgrade_db.8.xml | 95 ++++++++++++++++++++++ > docs-xml/wscript_build | 1 + > 2 files changed, 96 insertions(+) > create mode 100644 docs-xml/manpages/samba_downgrade_db.8.xml > >diff --git a/docs-xml/manpages/samba_downgrade_db.8.xml b/docs-xml/manpages/samba_downgrade_db.8.xml >new file mode 100644 >index 00000000000..7b0c822cf21 >--- /dev/null >+++ b/docs-xml/manpages/samba_downgrade_db.8.xml >@@ -0,0 +1,95 @@ >+<?xml version="1.0" encoding="iso-8859-1"?> >+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> >+<refentry id="samba_downgrade_db.8"> >+ >+<refmeta> >+ <refentrytitle>samba_downgrade_db</refentrytitle> >+ <manvolnum>8</manvolnum> >+ <refmiscinfo class="source">Samba</refmiscinfo> >+ <refmiscinfo class="manual">User Commands</refmiscinfo> >+ <refmiscinfo class="version">&doc.version;</refmiscinfo> >+</refmeta> >+ >+ >+<refnamediv> >+ <refname>samba_downgrade_db</refname> >+ <refpurpose>Samba tool for downgrading AD databases >+ </refpurpose> >+</refnamediv> >+ >+<refsynopsisdiv> >+ <cmdsynopsis> >+ <command>samba_downgrade_db</command> >+ <arg choice="opt">-H</arg> >+ <arg choice="opt">-s</arg> >+ </cmdsynopsis> >+</refsynopsisdiv> >+ >+<refsect1> >+ <title>DESCRIPTION</title> >+ <para>This tool is part of the <citerefentry><refentrytitle>samba</refentrytitle> >+ <manvolnum>8</manvolnum></citerefentry> suite.</para> >+ >+ <para>The format of the Samba Active Directory (AD) database changed in >+ version 4.8 and 4.11. When downgrading a Samba AD Domain Controller (DC) >+ to a release that is older than either of these versions (e.g. 4.11 to >+ 4.10), the AD database must be manually downgraded >+ <emphasis>before</emphasis> the Samba packages can be safely downgraded. >+ </para> >+ >+ <para>This tool downgrades a Samba sam.ldb database from the format >+ used in version &doc.version; to that of version 4.7. The v4.7 database >+ format can safely be read by any version of Samba. If necessary, later >+ versions of Samba will repack and reconfigure a v4.7-format database when >+ the samba executable is first started.</para> >+ >+ <para>Note that all Samba services must be stopped on the DC before running >+ this tool. Once the tool has run, do not restart samba or modify the >+ database before the Samba software package has been downgraded. >+ </para> >+</refsect1> >+ >+<refsect1> >+ <title>OPTIONS</title> >+ >+ <variablelist> >+ >+ <varlistentry> >+ <term>-H [sam.ldb file]</term> >+ <listitem><para> >+ Link directly to a sam.ldb file instead of using path in system >+ smb.conf >+ </para></listitem> >+ </varlistentry> >+ >+ <varlistentry> >+ <term>-s [smb.conf file]</term> >+ <listitem><para> >+ Link directly to smb.conf file instead of system default (usually >+ in /usr/local/samba/etc/smb.conf) >+ </para></listitem> >+ </varlistentry> >+ >+ </variablelist> >+</refsect1> >+ >+<refsect1> >+ <title>VERSION</title> >+ >+ <para>This man page is complete for version &doc.version; of the Samba >+ suite.</para> >+</refsect1> >+ >+<refsect1> >+ <title>AUTHOR</title> >+ >+ <para>The original Samba software and related utilities >+ were created by Andrew Tridgell. Samba is now developed >+ by the Samba Team as an Open Source project similar >+ to the way the Linux kernel is developed.</para> >+ >+ <para>The samba_downgrade_db tool was developed by the Samba team >+ at Catalyst IT Ltd.</para> >+</refsect1> >+ >+</refentry> >diff --git a/docs-xml/wscript_build b/docs-xml/wscript_build >index 575fb702b46..3dad0a21313 100644 >--- a/docs-xml/wscript_build >+++ b/docs-xml/wscript_build >@@ -31,6 +31,7 @@ manpages=''' > manpages/samba-tool.8 > manpages/samba.7 > manpages/samba.8 >+ manpages/samba_downgrade_db.8 > manpages/sharesec.1 > manpages/smbcacls.1 > manpages/smbclient.1 >-- >2.17.1 > > >From b3987205fe2770bd88ae5ee8e10a85cebf662ac0 Mon Sep 17 00:00:00 2001 >From: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Date: Mon, 22 Jul 2019 13:35:21 +1200 >Subject: [PATCH 074/376] downgradedatabase: installing script > >Installing downgrade script so people don't need the source tree for it. > >Exception added in usage test because running the script without arguments >is valid. (This avoids the need to knownfail it). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz> >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit 6dcf00ba0a470ba25aabae06b409ec95404c246f) >--- > python/samba/tests/usage.py | 2 ++ > selftest/knownfail.d/usage | 1 - > source4/scripting/bin/wscript_build | 3 ++- > source4/scripting/wscript_build | 2 +- > 4 files changed, 5 insertions(+), 3 deletions(-) > >diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py >index ba18a3e0729..4b7bccde758 100644 >--- a/python/samba/tests/usage.py >+++ b/python/samba/tests/usage.py >@@ -78,6 +78,8 @@ EXCLUDE_USAGE = { > 'selftest/tap2subunit', > 'script/show_test_time', > 'source4/scripting/bin/subunitrun', >+ 'bin/samba_downgrade_db', >+ 'source4/scripting/bin/samba_downgrade_db', > 'source3/selftest/tests.py', > 'selftest/tests.py', > 'python/samba/subunit/run.py', >diff --git a/selftest/knownfail.d/usage b/selftest/knownfail.d/usage >index 0a495858e8c..3e54f80a2de 100644 >--- a/selftest/knownfail.d/usage >+++ b/selftest/knownfail.d/usage >@@ -25,7 +25,6 @@ samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rebuildextendedd > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_renamedc.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_repl_cleartext_pwd_py.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_rodcdns.none. >-samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_downgrade_db.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_gpupdate_.none. > samba.tests.usage.samba.tests.usage.PythonScriptUsageTests.test_samba_kcc.none. >diff --git a/source4/scripting/bin/wscript_build b/source4/scripting/bin/wscript_build >index 42b37faa32a..87d23545487 100644 >--- a/source4/scripting/bin/wscript_build >+++ b/source4/scripting/bin/wscript_build >@@ -7,6 +7,7 @@ if bld.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): > 'samba_kcc', > 'samba_upgradeprovision', > 'samba_upgradedns', >- 'gen_output.py']: >+ 'gen_output.py', >+ 'samba_downgrade_db']: > bld.SAMBA_SCRIPT(script, pattern=script, installdir='.') > bld.SAMBA_SCRIPT('samba-gpupdate', pattern='samba-gpupdate', installdir='.') >diff --git a/source4/scripting/wscript_build b/source4/scripting/wscript_build >index df24e921cd9..31c395d3e4b 100644 >--- a/source4/scripting/wscript_build >+++ b/source4/scripting/wscript_build >@@ -4,7 +4,7 @@ from samba_utils import MODE_755 > > sbin_files = '' > if bld.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): >- sbin_files = 'bin/samba_dnsupdate bin/samba_spnupdate bin/samba_upgradedns bin/samba_kcc ' >+ sbin_files = 'bin/samba_downgrade_db bin/samba_dnsupdate bin/samba_spnupdate bin/samba_upgradedns bin/samba_kcc ' > sbin_files += 'bin/samba-gpupdate' > man_files = 'man/samba-gpupdate.8' > >-- >2.17.1 > > >From 70726f2dfba3907ebc11b196aba61fe8358ac989 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Tue, 30 Jul 2019 16:40:55 +1200 >Subject: [PATCH 075/376] ldb: Always log when the database pack format changes > >LDB_DEBUG_WARNING gets logged by Samba as level 2, whereas the default >log level for Samba is 0. It's not really fair to the user to change the >format of their database on disk and potentially not tell them. > >This patch adds a log with level zero (using a alias define, as this >technically isn't a fatal problem). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit a2b0fc7c00360f37ed6819f21380294b70d4a195) >--- > lib/ldb/include/ldb.h | 3 +++ > lib/ldb/ldb_key_value/ldb_kv_index.c | 2 +- > 2 files changed, 4 insertions(+), 1 deletion(-) > >diff --git a/lib/ldb/include/ldb.h b/lib/ldb/include/ldb.h >index f06d5e95528..3cba0f4d543 100644 >--- a/lib/ldb/include/ldb.h >+++ b/lib/ldb/include/ldb.h >@@ -220,6 +220,9 @@ struct tevent_context; > enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, > LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; > >+/* alias for something that's not a fatal error but we really want to log */ >+#define LDB_DEBUG_ALWAYS_LOG LDB_DEBUG_FATAL >+ > /** > the user can optionally supply a debug function. The function > is based on the vfprintf() style of interface, but with the addition >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index ef275b28013..5de316579d7 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -3571,7 +3571,7 @@ static int re_pack(struct ldb_kv_private *ldb_kv, > * want to spam the log. > */ > if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { >- ldb_debug(ldb, LDB_DEBUG_WARNING, >+ ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, > "Repacking database with format %#010x", > ldb_kv->pack_format_version); > ctx->normal_record_seen = true; >-- >2.17.1 > > >From b99fff86ebb64e31fd3577164f55246705511c3b Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Tue, 30 Jul 2019 15:02:25 +1200 >Subject: [PATCH 076/376] ldb: Move where we update the pack format version > >Store it on the repack context so that we can log a more informative >message "Repacking from format x to format y". > >While this is not really a big deal currently, it could be worth >recording for potential future scenarios (i.e. supporting three or more >pack versions), where upgrades could potentially skip an intermediary >pack format version. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit d427bd6c775d8117504e76eed42cd2c383512e34) >--- > lib/ldb/ldb_key_value/ldb_kv.c | 2 -- > lib/ldb/ldb_key_value/ldb_kv.h | 1 + > lib/ldb/ldb_key_value/ldb_kv_index.c | 3 +++ > 3 files changed, 4 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/ldb_key_value/ldb_kv.c b/lib/ldb/ldb_key_value/ldb_kv.c >index f768fb5e1e4..4e7b8a116b3 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv.c >+++ b/lib/ldb/ldb_key_value/ldb_kv.c >@@ -315,8 +315,6 @@ static int ldb_kv_maybe_repack(struct ldb_kv_private *ldb_kv) { > ldb_kv->target_pack_format_version) { > int r; > struct ldb_context *ldb = ldb_module_get_ctx(ldb_kv->module); >- ldb_kv->pack_format_version = >- ldb_kv->target_pack_format_version; > r = ldb_kv_repack(ldb_kv->module); > if (r != LDB_SUCCESS) { > ldb_debug(ldb, LDB_DEBUG_ERROR, >diff --git a/lib/ldb/ldb_key_value/ldb_kv.h b/lib/ldb/ldb_key_value/ldb_kv.h >index e627644ba34..f9dffae2dcf 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv.h >+++ b/lib/ldb/ldb_key_value/ldb_kv.h >@@ -175,6 +175,7 @@ struct ldb_kv_repack_context { > int error; > uint32_t count; > bool normal_record_seen; >+ uint32_t old_version; > }; > > >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index 5de316579d7..eb84a790e00 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -3595,10 +3595,13 @@ int ldb_kv_repack(struct ldb_module *module) > struct ldb_kv_repack_context ctx; > int ret; > >+ ctx.old_version = ldb_kv->pack_format_version; > ctx.count = 0; > ctx.error = LDB_SUCCESS; > ctx.normal_record_seen = false; > >+ ldb_kv->pack_format_version = ldb_kv->target_pack_format_version; >+ > /* Iterate all database records and repack them in the new format */ > ret = ldb_kv->kv_ops->iterate(ldb_kv, re_pack, &ctx); > if (ret < 0) { >-- >2.17.1 > > >From 6de3d8f7ce0f97810515b81f4da1a7cc1eb4a241 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Tue, 30 Jul 2019 15:15:40 +1200 >Subject: [PATCH 077/376] ldb: Change pack format defines to enum > >The main reason is so that any future pack formats will continue >incrementing this number in a sequential fashion. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit 38e3e7cd328edac302e95ac8839e858c4a225485) >--- > lib/ldb/include/ldb_module.h | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > >diff --git a/lib/ldb/include/ldb_module.h b/lib/ldb/include/ldb_module.h >index ab3d25c5c6e..8c1e5ee7936 100644 >--- a/lib/ldb/include/ldb_module.h >+++ b/lib/ldb/include/ldb_module.h >@@ -559,12 +559,15 @@ int ldb_unpack_get_format(const struct ldb_val *data, > #define LDB_UNPACK_DATA_FLAG_NO_ATTRS 0x0008 > #define LDB_UNPACK_DATA_FLAG_READ_LOCKED 0x0010 > >-/* In-use packing formats */ >-#define LDB_PACKING_FORMAT 0x26011967 >-#define LDB_PACKING_FORMAT_V2 0x26011968 >+enum ldb_pack_format { > >-/* Old packing formats */ >-#define LDB_PACKING_FORMAT_NODN 0x26011966 >+ /* Old packing format (based on a somewhat arbitrary date) */ >+ LDB_PACKING_FORMAT_NODN = 0x26011966, >+ >+ /* In-use packing formats */ >+ LDB_PACKING_FORMAT, >+ LDB_PACKING_FORMAT_V2 >+}; > > /** > Forces a specific ldb handle to use the global event context. >-- >2.17.1 > > >From 1c2f1bd04abbedb3cfb31bb4a0ee4292c21dacc4 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Tue, 30 Jul 2019 16:40:55 +1200 >Subject: [PATCH 078/376] ldb: Log pack format in user-friendly way > >The "format 0x26011968" log confused me (and I'm a developer). >We can subtract the base offset from the pack format to get a more >user-friendly number, e.g. v0 (not actually used), v1, v2, etc. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit 5fee9388422e259c2a56e4dccbf44d22ba426ca3) >--- > lib/ldb/ldb_key_value/ldb_kv_index.c | 17 +++++++++++++++-- > 1 file changed, 15 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index eb84a790e00..27454d3f734 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -3526,6 +3526,18 @@ static int re_index(struct ldb_kv_private *ldb_kv, > return 0; > } > >+/* >+ * Convert the 4-byte pack format version to a number that's slightly >+ * more intelligible to a user e.g. version 0, 1, 2, etc. >+ */ >+static uint32_t displayable_pack_version(uint32_t version) { >+ if (version < LDB_PACKING_FORMAT_NODN) { >+ return version; /* unknown - can't convert */ >+ } >+ >+ return (version - LDB_PACKING_FORMAT_NODN); >+} >+ > static int re_pack(struct ldb_kv_private *ldb_kv, > _UNUSED_ struct ldb_val key, > struct ldb_val val, >@@ -3572,8 +3584,9 @@ static int re_pack(struct ldb_kv_private *ldb_kv, > */ > if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { > ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, >- "Repacking database with format %#010x", >- ldb_kv->pack_format_version); >+ "Repacking database from v%u to v%u format", >+ displayable_pack_version(ctx->old_version), >+ displayable_pack_version(ldb_kv->pack_format_version)); > ctx->normal_record_seen = true; > } > >-- >2.17.1 > > >From 18fb5fb911d098701e4af732977310e48ed403a9 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 31 Jul 2019 10:33:49 +1200 >Subject: [PATCH 079/376] ldb: Log the partition we're repacking > >Firstly, with Samba AD this looks a little weird because we log the same >message 5 times (once for every partition). If we log that we're doing >this to records in different partitions, hopefully someone with a little >Samba knowledge can figure out what's going on. > >Secondly, the info about what partitions are actually changing might be >useful. E.g. if we hit a fatal error repacking the 3rd partition, and >the transaction doesn't abort properly, then it would be useful to know >what partitions were repacked and which ones weren't. > >There doesn't appear to be a useful name for the partition >(ldb_kv->kv_ops->name() doesn't seem any more intelligible to a user), >so just log the first record that we update. We can use that to infer >the partition database). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit ee6537c29e747206ee607493ce15d4532fb670c8) >--- > lib/ldb/ldb_key_value/ldb_kv_index.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index 27454d3f734..d955517ea10 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -3584,9 +3584,11 @@ static int re_pack(struct ldb_kv_private *ldb_kv, > */ > if ((!ctx->normal_record_seen) && (!ldb_dn_is_special(msg->dn))) { > ldb_debug(ldb, LDB_DEBUG_ALWAYS_LOG, >- "Repacking database from v%u to v%u format", >+ "Repacking database from v%u to v%u format " >+ "(first record %s)", > displayable_pack_version(ctx->old_version), >- displayable_pack_version(ldb_kv->pack_format_version)); >+ displayable_pack_version(ldb_kv->pack_format_version), >+ ldb_dn_get_linearized(msg->dn)); > ctx->normal_record_seen = true; > } > >-- >2.17.1 > > >From d819a1c20503484b3624aeda426a37912a4ee692 Mon Sep 17 00:00:00 2001 >From: Tim Beale <timbeale@catalyst.net.nz> >Date: Wed, 31 Jul 2019 10:54:29 +1200 >Subject: [PATCH 080/376] ldb: Free memory when repacking database > >The msg for each database record is allocated on the module context, but >never freed. The module seems like it could be a long-running context (as >the database would normally get repacked by the samba executable). > >Even if it's not a proper leak, it shouldn't hurt to cleanup the memory. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> > >Autobuild-User(master): Garming Sam <garming@samba.org> >Autobuild-Date(master): Tue Aug 20 04:57:10 UTC 2019 on sn-devel-184 > >(cherry picked from commit b6516dbd24df8c78ed909c7ef9058b0844abb917) >--- > lib/ldb/ldb_key_value/ldb_kv_index.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/lib/ldb/ldb_key_value/ldb_kv_index.c b/lib/ldb/ldb_key_value/ldb_kv_index.c >index d955517ea10..0853b28fe40 100644 >--- a/lib/ldb/ldb_key_value/ldb_kv_index.c >+++ b/lib/ldb/ldb_key_value/ldb_kv_index.c >@@ -3599,6 +3599,7 @@ static int re_pack(struct ldb_kv_private *ldb_kv, > ctx->count); > } > >+ talloc_free(msg); > return 0; > } > >-- >2.17.1 > > >From 80bd467affbda1d962f4deb3caa8a42c6531425d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 23 Aug 2019 12:02:05 +1200 >Subject: [PATCH 081/376] ldb: Release ldb 2.0.6 > > * log database repack so users know what is happening > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14059 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >--- > lib/ldb/ABI/ldb-2.0.6.sigs | 283 ++++++++++++++++++++++++++++++ > lib/ldb/ABI/pyldb-util-2.0.6.sigs | 2 + > lib/ldb/wscript | 2 +- > 3 files changed, 286 insertions(+), 1 deletion(-) > create mode 100644 lib/ldb/ABI/ldb-2.0.6.sigs > create mode 100644 lib/ldb/ABI/pyldb-util-2.0.6.sigs > >diff --git a/lib/ldb/ABI/ldb-2.0.6.sigs b/lib/ldb/ABI/ldb-2.0.6.sigs >new file mode 100644 >index 00000000000..5049dc64ce1 >--- /dev/null >+++ b/lib/ldb/ABI/ldb-2.0.6.sigs >@@ -0,0 +1,283 @@ >+ldb_add: int (struct ldb_context *, const struct ldb_message *) >+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) >+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) >+ldb_attr_casefold: char *(TALLOC_CTX *, const char *) >+ldb_attr_dn: int (const char *) >+ldb_attr_in_list: int (const char * const *, const char *) >+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) >+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) >+ldb_base64_decode: int (char *) >+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) >+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) >+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) >+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) >+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) >+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) >+ldb_check_critical_controls: int (struct ldb_control **) >+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) >+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) >+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) >+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_debug_add: void (struct ldb_context *, const char *, ...) >+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) >+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_delete: int (struct ldb_context *, struct ldb_dn *) >+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) >+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) >+ldb_dn_check_special: bool (struct ldb_dn *, const char *) >+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) >+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) >+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) >+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) >+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) >+ldb_dn_get_casefold: const char *(struct ldb_dn *) >+ldb_dn_get_comp_num: int (struct ldb_dn *) >+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) >+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) >+ldb_dn_get_extended_comp_num: int (struct ldb_dn *) >+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) >+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) >+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) >+ldb_dn_get_linearized: const char *(struct ldb_dn *) >+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_get_rdn_name: const char *(struct ldb_dn *) >+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) >+ldb_dn_has_extended: bool (struct ldb_dn *) >+ldb_dn_is_null: bool (struct ldb_dn *) >+ldb_dn_is_special: bool (struct ldb_dn *) >+ldb_dn_is_valid: bool (struct ldb_dn *) >+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_minimise: bool (struct ldb_dn *) >+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) >+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) >+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_extended_components: void (struct ldb_dn *) >+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) >+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) >+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) >+ldb_dn_validate: bool (struct ldb_dn *) >+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) >+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) >+ldb_errstring: const char *(struct ldb_context *) >+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) >+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) >+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_create_perms: unsigned int (struct ldb_context *) >+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_event_context: struct tevent_context *(struct ldb_context *) >+ldb_get_flags: unsigned int (struct ldb_context *) >+ldb_get_opaque: void *(struct ldb_context *, const char *) >+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_global_init: int (void) >+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) >+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) >+ldb_handle_use_global_event_context: void (struct ldb_handle *) >+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) >+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) >+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) >+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) >+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) >+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) >+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) >+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) >+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) >+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_load_modules: int (struct ldb_context *, const char **) >+ldb_map_add: int (struct ldb_module *, struct ldb_request *) >+ldb_map_delete: int (struct ldb_module *, struct ldb_request *) >+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) >+ldb_map_modify: int (struct ldb_module *, struct ldb_request *) >+ldb_map_rename: int (struct ldb_module *, struct ldb_request *) >+ldb_map_search: int (struct ldb_module *, struct ldb_request *) >+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) >+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) >+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) >+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) >+ldb_mod_register_control: int (struct ldb_module *, const char *) >+ldb_modify: int (struct ldb_context *, const struct ldb_message *) >+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) >+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) >+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) >+ldb_module_flags: uint32_t (struct ldb_context *) >+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) >+ldb_module_get_name: const char *(struct ldb_module *) >+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) >+ldb_module_get_private: void *(struct ldb_module *) >+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) >+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) >+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) >+ldb_module_next: struct ldb_module *(struct ldb_module *) >+ldb_module_popt_options: struct poptOption **(struct ldb_context *) >+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) >+ldb_module_send_referral: int (struct ldb_request *, char *) >+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) >+ldb_module_set_private: void (struct ldb_module *, void *) >+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) >+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_modules_load: int (const char *, const char *) >+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) >+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) >+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) >+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) >+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) >+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) >+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) >+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) >+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) >+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) >+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) >+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) >+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) >+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) >+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) >+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) >+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) >+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) >+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) >+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) >+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) >+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) >+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) >+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) >+ldb_msg_new: struct ldb_message *(TALLOC_CTX *) >+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) >+ldb_msg_remove_attr: void (struct ldb_message *, const char *) >+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) >+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) >+ldb_msg_sort_elements: void (struct ldb_message *) >+ldb_next_del_trans: int (struct ldb_module *) >+ldb_next_end_trans: int (struct ldb_module *) >+ldb_next_init: int (struct ldb_module *) >+ldb_next_prepare_commit: int (struct ldb_module *) >+ldb_next_read_lock: int (struct ldb_module *) >+ldb_next_read_unlock: int (struct ldb_module *) >+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_start_trans: int (struct ldb_module *) >+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_options_copy: const char **(TALLOC_CTX *, const char **) >+ldb_options_find: const char *(struct ldb_context *, const char **, const char *) >+ldb_options_get: const char **(struct ldb_context *) >+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) >+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) >+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) >+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) >+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) >+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) >+ldb_register_backend: int (const char *, ldb_connect_fn, bool) >+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) >+ldb_register_hook: int (ldb_hook_fn) >+ldb_register_module: int (const struct ldb_module_ops *) >+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) >+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) >+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) >+ldb_req_get_custom_flags: uint32_t (struct ldb_request *) >+ldb_req_is_untrusted: bool (struct ldb_request *) >+ldb_req_location: const char *(struct ldb_request *) >+ldb_req_mark_trusted: void (struct ldb_request *) >+ldb_req_mark_untrusted: void (struct ldb_request *) >+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) >+ldb_req_set_location: void (struct ldb_request *, const char *) >+ldb_request: int (struct ldb_context *, struct ldb_request *) >+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_done: int (struct ldb_request *, int) >+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) >+ldb_request_get_status: int (struct ldb_request *) >+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_set_state: void (struct ldb_request *, int) >+ldb_reset_err_string: void (struct ldb_context *) >+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) >+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) >+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) >+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) >+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) >+ldb_schema_attribute_remove: void (struct ldb_context *, const char *) >+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) >+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) >+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) >+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) >+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) >+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) >+ldb_set_create_perms: void (struct ldb_context *, unsigned int) >+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) >+ldb_set_debug_stderr: int (struct ldb_context *) >+ldb_set_default_dns: void (struct ldb_context *) >+ldb_set_errstring: void (struct ldb_context *, const char *) >+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) >+ldb_set_flags: void (struct ldb_context *, unsigned int) >+ldb_set_modules_dir: void (struct ldb_context *, const char *) >+ldb_set_opaque: int (struct ldb_context *, const char *, void *) >+ldb_set_require_private_event_context: void (struct ldb_context *) >+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) >+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) >+ldb_set_utf8_default: void (struct ldb_context *) >+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) >+ldb_setup_wellknown_attributes: int (struct ldb_context *) >+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) >+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) >+ldb_strerror: const char *(int) >+ldb_string_to_time: time_t (const char *) >+ldb_string_utc_to_time: time_t (const char *) >+ldb_timestring: char *(TALLOC_CTX *, time_t) >+ldb_timestring_utc: char *(TALLOC_CTX *, time_t) >+ldb_transaction_cancel: int (struct ldb_context *) >+ldb_transaction_cancel_noerr: int (struct ldb_context *) >+ldb_transaction_commit: int (struct ldb_context *) >+ldb_transaction_prepare_commit: int (struct ldb_context *) >+ldb_transaction_start: int (struct ldb_context *) >+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) >+ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) >+ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) >+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) >+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) >+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_string_cmp: int (const struct ldb_val *, const char *) >+ldb_val_to_time: int (const struct ldb_val *, time_t *) >+ldb_valid_attr_name: int (const char *) >+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) >+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) >diff --git a/lib/ldb/ABI/pyldb-util-2.0.6.sigs b/lib/ldb/ABI/pyldb-util-2.0.6.sigs >new file mode 100644 >index 00000000000..74d6719d2bc >--- /dev/null >+++ b/lib/ldb/ABI/pyldb-util-2.0.6.sigs >@@ -0,0 +1,2 @@ >+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) >+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) >diff --git a/lib/ldb/wscript b/lib/ldb/wscript >index 61f6b664902..a63a6c2171f 100644 >--- a/lib/ldb/wscript >+++ b/lib/ldb/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'ldb' >-VERSION = '2.0.5' >+VERSION = '2.0.6' > > import sys, os > >-- >2.17.1 > > >From 756bea42e0c051580330680dd6350cefb102a21c Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 12 Aug 2019 16:11:13 +1000 >Subject: [PATCH 082/376] ctdb-tools: Drop 'o' option from getopts command > >Commit 90de5e0594b9180226b9a13293afe31f18576b3d remove the processing >for this option but forgot to remove it from the getopts command. > >Versions of ShellCheck >= 0.4.7 warn on this, so it is worth fixing. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14086 >RN: Fix onnode test failure with ShellCheck >= 0.4.7 >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 758962a0d435fa595e3917b860a8fd266d122550) >--- > ctdb/tools/onnode | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/ctdb/tools/onnode b/ctdb/tools/onnode >index e143ba2d4d4..d6595fff4aa 100755 >--- a/ctdb/tools/onnode >+++ b/ctdb/tools/onnode >@@ -72,7 +72,7 @@ parse_options () > { > local opt > >- while getopts "cf:hno:pqvPi?" opt ; do >+ while getopts "cf:hnpqvPi?" opt ; do > case "$opt" in > c) current=true ;; > f) ctdb_nodes_file="$OPTARG" ;; >-- >2.17.1 > > >From 900cc33accf07f5c80c941b7dc74e374185e2808 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 14 Aug 2019 10:06:00 +0200 >Subject: [PATCH 083/376] vfs_default: use correct flag in vfswrap_fs_file_id > >Luckily using the wrong flag ST_EX_IFLAG_CALCULATED_ITIME currently results in >the same semantics as using the correct ST_EX_IFLAG_CALCULATED_FILE_ID, as in >vfs_default the non-calculated file_id is based a non-calculated itime. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14089 >RN: vfs_default: use correct flag in vfswrap_fs_file_id > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 442a7c9ad8b020b2e88e41fea8a911d244023cb9) >--- > source3/modules/vfs_default.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index 84c22bb1517..5095f65b746 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -2733,7 +2733,7 @@ static uint64_t vfswrap_fs_file_id(struct vfs_handle_struct *handle, > { > uint64_t file_id; > >- if (!(psbuf->st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) { >+ if (!(psbuf->st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)) { > return psbuf->st_ex_file_id; > } > >-- >2.17.1 > > >From 53f828969d0fde5cabd61e5a260a887c53fdc872 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Wed, 14 Aug 2019 10:11:15 +0200 >Subject: [PATCH 084/376] vfs_glusterfs: initialize st_ex_file_id, st_ex_itime > and st_ex_iflags > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14090 >RN: vfs_glusterfs: initialize st_ex_file_id, st_ex_itime and st_ex_iflags > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Fri Aug 16 01:07:23 UTC 2019 on sn-devel-184 > >(cherry picked from commit 3ee78cc9979a72ebbe65a16c60967a1735a0d208) >--- > source3/modules/vfs_glusterfs.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 95f32f9d0a6..56e03014fea 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -74,12 +74,16 @@ static void smb_stat_ex_from_stat(struct stat_ex *dst, const struct stat *src) > dst->st_ex_btime.tv_sec = src->st_mtime; > dst->st_ex_blksize = src->st_blksize; > dst->st_ex_blocks = src->st_blocks; >+ dst->st_ex_file_id = dst->st_ex_ino; >+ dst->st_ex_iflags |= ST_EX_IFLAG_CALCULATED_FILE_ID; > #ifdef STAT_HAVE_NSEC > dst->st_ex_atime.tv_nsec = src->st_atime_nsec; > dst->st_ex_mtime.tv_nsec = src->st_mtime_nsec; > dst->st_ex_ctime.tv_nsec = src->st_ctime_nsec; > dst->st_ex_btime.tv_nsec = src->st_mtime_nsec; > #endif >+ dst->st_ex_itime = dst->st_ex_btime; >+ dst->st_ex_iflags |= ST_EX_IFLAG_CALCULATED_ITIME; > } > > /* pre-opened glfs_t */ >-- >2.17.1 > > >From c6d784debd8a9f9e576397a628de1e581aa7adbc Mon Sep 17 00:00:00 2001 >From: Anoop C S <anoopcs@redhat.com> >Date: Mon, 5 Aug 2019 10:45:01 +0530 >Subject: [PATCH 085/376] vfs_glusterfs: Enable profiling for file system > operations > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14093 > >Signed-off-by: Anoop C S <anoopcs@redhat.com> >Reviewed-by: Guenther Deschner <gd@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Tue Aug 20 19:25:28 UTC 2019 on sn-devel-184 > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Mon Aug 26 08:51:55 UTC 2019 on sn-devel-184 >--- > source3/modules/vfs_glusterfs.c | 337 +++++++++++++++++++++++++++----- > 1 file changed, 288 insertions(+), 49 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 56e03014fea..483d28397f8 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -492,12 +492,16 @@ static DIR *vfs_gluster_opendir(struct vfs_handle_struct *handle, > { > glfs_fd_t *fd; > >+ START_PROFILE(syscall_opendir); >+ > fd = glfs_opendir(handle->data, smb_fname->base_name); > if (fd == NULL) { > DEBUG(0, ("glfs_opendir(%s) failed: %s\n", > smb_fname->base_name, strerror(errno))); > } > >+ END_PROFILE(syscall_opendir); >+ > return (DIR *) fd; > } > >@@ -532,7 +536,13 @@ static DIR *vfs_gluster_fdopendir(struct vfs_handle_struct *handle, > > static int vfs_gluster_closedir(struct vfs_handle_struct *handle, DIR *dirp) > { >- return glfs_closedir((void *)dirp); >+ int ret; >+ >+ START_PROFILE(syscall_closedir); >+ ret = glfs_closedir((void *)dirp); >+ END_PROFILE(syscall_closedir); >+ >+ return ret; > } > > static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle, >@@ -543,6 +553,7 @@ static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle, > struct stat stat; > struct dirent *dirent = 0; > >+ START_PROFILE(syscall_readdir); > if (sbuf != NULL) { > ret = glfs_readdirplus_r((void *)dirp, &stat, (void *)direntbuf, > &dirent); >@@ -551,6 +562,7 @@ static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle, > } > > if ((ret < 0) || (dirent == NULL)) { >+ END_PROFILE(syscall_readdir); > return NULL; > } > >@@ -558,36 +570,59 @@ static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle, > smb_stat_ex_from_stat(sbuf, &stat); > } > >+ END_PROFILE(syscall_readdir); > return dirent; > } > > static long vfs_gluster_telldir(struct vfs_handle_struct *handle, DIR *dirp) > { >- return glfs_telldir((void *)dirp); >+ long ret; >+ >+ START_PROFILE(syscall_telldir); >+ ret = glfs_telldir((void *)dirp); >+ END_PROFILE(syscall_telldir); >+ >+ return ret; > } > > static void vfs_gluster_seekdir(struct vfs_handle_struct *handle, DIR *dirp, > long offset) > { >+ START_PROFILE(syscall_seekdir); > glfs_seekdir((void *)dirp, offset); >+ END_PROFILE(syscall_seekdir); > } > > static void vfs_gluster_rewinddir(struct vfs_handle_struct *handle, DIR *dirp) > { >+ START_PROFILE(syscall_rewinddir); > glfs_seekdir((void *)dirp, 0); >+ END_PROFILE(syscall_rewinddir); > } > > static int vfs_gluster_mkdir(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname, > mode_t mode) > { >- return glfs_mkdir(handle->data, smb_fname->base_name, mode); >+ int ret; >+ >+ START_PROFILE(syscall_mkdir); >+ ret = glfs_mkdir(handle->data, smb_fname->base_name, mode); >+ END_PROFILE(syscall_mkdir); >+ >+ return ret; > } > > static int vfs_gluster_rmdir(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname) > { >- return glfs_rmdir(handle->data, smb_fname->base_name); >+ int ret; >+ >+ START_PROFILE(syscall_rmdir); >+ ret = glfs_rmdir(handle->data, smb_fname->base_name); >+ END_PROFILE(syscall_rmdir); >+ >+ return ret; > } > > static int vfs_gluster_open(struct vfs_handle_struct *handle, >@@ -597,8 +632,11 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, > glfs_fd_t *glfd; > glfs_fd_t **p_tmp; > >+ START_PROFILE(syscall_open); >+ > p_tmp = VFS_ADD_FSP_EXTENSION(handle, fsp, glfs_fd_t *, NULL); > if (p_tmp == NULL) { >+ END_PROFILE(syscall_open); > errno = ENOMEM; > return -1; > } >@@ -613,12 +651,15 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, > } > > if (glfd == NULL) { >+ END_PROFILE(syscall_open); > /* no extension destroy_fn, so no need to save errno */ > VFS_REMOVE_FSP_EXTENSION(handle, fsp); > return -1; > } > > *p_tmp = glfd; >+ >+ END_PROFILE(syscall_open); > /* An arbitrary value for error reporting, so you know its us. */ > return 13371337; > } >@@ -626,31 +667,50 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, > static int vfs_gluster_close(struct vfs_handle_struct *handle, > files_struct *fsp) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ int ret; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_close); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_close); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > > VFS_REMOVE_FSP_EXTENSION(handle, fsp); >- return glfs_close(glfd); >+ >+ ret = glfs_close(glfd); >+ END_PROFILE(syscall_close); >+ >+ return ret; > } > > static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, > files_struct *fsp, void *data, size_t n, > off_t offset) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ ssize_t ret; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE_BYTES(syscall_pread, n); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE_BYTES(syscall_pread); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > > #ifdef HAVE_GFAPI_VER_7_6 >- return glfs_pread(glfd, data, n, offset, 0, NULL); >+ ret = glfs_pread(glfd, data, n, offset, 0, NULL); > #else >- return glfs_pread(glfd, data, n, offset, 0); >+ ret = glfs_pread(glfd, data, n, offset, 0); > #endif >+ END_PROFILE_BYTES(syscall_pread); >+ >+ return ret; > } > > struct glusterfs_aio_state; >@@ -665,6 +725,7 @@ struct glusterfs_aio_state { > bool cancelled; > struct vfs_aio_state vfs_aio_state; > struct timespec start; >+ SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes); > }; > > static int aio_wrapper_destructor(struct glusterfs_aio_wrapper *wrap) >@@ -706,6 +767,8 @@ static void aio_glusterfs_done(glfs_fd_t *fd, ssize_t ret, void *data) > } > state->vfs_aio_state.duration = nsec_time_diff(&end, &state->start); > >+ SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); >+ > /* > * Write the state pointer to glusterfs_aio_state to the > * pipe, so we can call tevent_req_done() from the main thread, >@@ -878,6 +941,8 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct > */ > tevent_req_defer_callback(req, ev); > >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread, profile_p, >+ state->profile_bytes, n); > PROFILE_TIMESTAMP(&state->start); > ret = glfs_pread_async(glfd, data, n, offset, 0, aio_glusterfs_done, > state); >@@ -927,6 +992,8 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct > */ > tevent_req_defer_callback(req, ev); > >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p, >+ state->profile_bytes, n); > PROFILE_TIMESTAMP(&state->start); > ret = glfs_pwrite_async(glfd, data, n, offset, 0, aio_glusterfs_done, > state); >@@ -972,29 +1039,47 @@ static ssize_t vfs_gluster_pwrite(struct vfs_handle_struct *handle, > files_struct *fsp, const void *data, > size_t n, off_t offset) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ ssize_t ret; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE_BYTES(syscall_pwrite, n); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE_BYTES(syscall_pwrite); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > > #ifdef HAVE_GFAPI_VER_7_6 >- return glfs_pwrite(glfd, data, n, offset, 0, NULL, NULL); >+ ret = glfs_pwrite(glfd, data, n, offset, 0, NULL, NULL); > #else >- return glfs_pwrite(glfd, data, n, offset, 0); >+ ret = glfs_pwrite(glfd, data, n, offset, 0); > #endif >+ END_PROFILE_BYTES(syscall_pwrite); >+ >+ return ret; > } > > static off_t vfs_gluster_lseek(struct vfs_handle_struct *handle, > files_struct *fsp, off_t offset, int whence) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ off_t ret = 0; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_lseek); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_lseek); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > >- return glfs_lseek(glfd, offset, whence); >+ ret = glfs_lseek(glfd, offset, whence); >+ END_PROFILE(syscall_lseek); >+ >+ return ret; > } > > static ssize_t vfs_gluster_sendfile(struct vfs_handle_struct *handle, int tofd, >@@ -1018,8 +1103,14 @@ static int vfs_gluster_rename(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname_src, > const struct smb_filename *smb_fname_dst) > { >- return glfs_rename(handle->data, smb_fname_src->base_name, >- smb_fname_dst->base_name); >+ int ret; >+ >+ START_PROFILE(syscall_rename); >+ ret = glfs_rename(handle->data, smb_fname_src->base_name, >+ smb_fname_dst->base_name); >+ END_PROFILE(syscall_rename); >+ >+ return ret; > } > > static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct >@@ -1058,6 +1149,8 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct > */ > tevent_req_defer_callback(req, ev); > >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_fsync, profile_p, >+ state->profile_bytes, 0); > PROFILE_TIMESTAMP(&state->start); > ret = glfs_fsync_async(glfd, aio_glusterfs_done, state); > if (ret < 0) { >@@ -1082,6 +1175,7 @@ static int vfs_gluster_stat(struct vfs_handle_struct *handle, > struct stat st; > int ret; > >+ START_PROFILE(syscall_stat); > ret = glfs_stat(handle->data, smb_fname->base_name, &st); > if (ret == 0) { > smb_stat_ex_from_stat(&smb_fname->st, &st); >@@ -1090,6 +1184,8 @@ static int vfs_gluster_stat(struct vfs_handle_struct *handle, > DEBUG(0, ("glfs_stat(%s) failed: %s\n", > smb_fname->base_name, strerror(errno))); > } >+ END_PROFILE(syscall_stat); >+ > return ret; > } > >@@ -1098,9 +1194,13 @@ static int vfs_gluster_fstat(struct vfs_handle_struct *handle, > { > struct stat st; > int ret; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_fstat); > >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_fstat); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } >@@ -1113,6 +1213,8 @@ static int vfs_gluster_fstat(struct vfs_handle_struct *handle, > DEBUG(0, ("glfs_fstat(%d) failed: %s\n", > fsp->fh->fd, strerror(errno))); > } >+ END_PROFILE(syscall_fstat); >+ > return ret; > } > >@@ -1122,6 +1224,7 @@ static int vfs_gluster_lstat(struct vfs_handle_struct *handle, > struct stat st; > int ret; > >+ START_PROFILE(syscall_lstat); > ret = glfs_lstat(handle->data, smb_fname->base_name, &st); > if (ret == 0) { > smb_stat_ex_from_stat(&smb_fname->st, &st); >@@ -1130,6 +1233,8 @@ static int vfs_gluster_lstat(struct vfs_handle_struct *handle, > DEBUG(0, ("glfs_lstat(%s) failed: %s\n", > smb_fname->base_name, strerror(errno))); > } >+ END_PROFILE(syscall_lstat); >+ > return ret; > } > >@@ -1137,33 +1242,59 @@ static uint64_t vfs_gluster_get_alloc_size(struct vfs_handle_struct *handle, > files_struct *fsp, > const SMB_STRUCT_STAT *sbuf) > { >- return sbuf->st_ex_blocks * 512; >+ uint64_t ret; >+ >+ START_PROFILE(syscall_get_alloc_size); >+ ret = sbuf->st_ex_blocks * 512; >+ END_PROFILE(syscall_get_alloc_size); >+ >+ return ret; > } > > static int vfs_gluster_unlink(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname) > { >- return glfs_unlink(handle->data, smb_fname->base_name); >+ int ret; >+ >+ START_PROFILE(syscall_unlink); >+ ret = glfs_unlink(handle->data, smb_fname->base_name); >+ END_PROFILE(syscall_unlink); >+ >+ return ret; > } > > static int vfs_gluster_chmod(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname, > mode_t mode) > { >- return glfs_chmod(handle->data, smb_fname->base_name, mode); >+ int ret; >+ >+ START_PROFILE(syscall_chmod); >+ ret = glfs_chmod(handle->data, smb_fname->base_name, mode); >+ END_PROFILE(syscall_chmod); >+ >+ return ret; > } > > static int vfs_gluster_fchmod(struct vfs_handle_struct *handle, > files_struct *fsp, mode_t mode) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ int ret; >+ glfs_fd_t *glfd = NULL; > >+ START_PROFILE(syscall_fchmod); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_fchmod); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > >- return glfs_fchmod(glfd, mode); >+ ret = glfs_fchmod(glfd, mode); >+ END_PROFILE(syscall_fchmod); >+ >+ return ret; > } > > static int vfs_gluster_chown(struct vfs_handle_struct *handle, >@@ -1171,19 +1302,34 @@ static int vfs_gluster_chown(struct vfs_handle_struct *handle, > uid_t uid, > gid_t gid) > { >- return glfs_chown(handle->data, smb_fname->base_name, uid, gid); >+ int ret; >+ >+ START_PROFILE(syscall_chown); >+ ret = glfs_chown(handle->data, smb_fname->base_name, uid, gid); >+ END_PROFILE(syscall_chown); >+ >+ return ret; > } > > static int vfs_gluster_fchown(struct vfs_handle_struct *handle, > files_struct *fsp, uid_t uid, gid_t gid) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ int ret; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_fchown); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_fchown); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > >- return glfs_fchown(glfd, uid, gid); >+ ret = glfs_fchown(glfd, uid, gid); >+ END_PROFILE(syscall_fchown); >+ >+ return ret; > } > > static int vfs_gluster_lchown(struct vfs_handle_struct *handle, >@@ -1191,13 +1337,25 @@ static int vfs_gluster_lchown(struct vfs_handle_struct *handle, > uid_t uid, > gid_t gid) > { >- return glfs_lchown(handle->data, smb_fname->base_name, uid, gid); >+ int ret; >+ >+ START_PROFILE(syscall_lchown); >+ ret = glfs_lchown(handle->data, smb_fname->base_name, uid, gid); >+ END_PROFILE(syscall_lchown); >+ >+ return ret; > } > > static int vfs_gluster_chdir(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname) > { >- return glfs_chdir(handle->data, smb_fname->base_name); >+ int ret; >+ >+ START_PROFILE(syscall_chdir); >+ ret = glfs_chdir(handle->data, smb_fname->base_name); >+ END_PROFILE(syscall_chdir); >+ >+ return ret; > } > > static struct smb_filename *vfs_gluster_getwd(struct vfs_handle_struct *handle, >@@ -1207,12 +1365,17 @@ static struct smb_filename *vfs_gluster_getwd(struct vfs_handle_struct *handle, > char *ret; > struct smb_filename *smb_fname = NULL; > >+ START_PROFILE(syscall_getwd); >+ > cwd = SMB_CALLOC_ARRAY(char, PATH_MAX); > if (cwd == NULL) { >+ END_PROFILE(syscall_getwd); > return NULL; > } > > ret = glfs_getcwd(handle->data, cwd, PATH_MAX - 1); >+ END_PROFILE(syscall_getwd); >+ > if (ret == NULL) { > SAFE_FREE(cwd); > return NULL; >@@ -1230,8 +1393,11 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, > const struct smb_filename *smb_fname, > struct smb_file_time *ft) > { >+ int ret = -1; > struct timespec times[2]; > >+ START_PROFILE(syscall_ntimes); >+ > if (null_timespec(ft->atime)) { > times[0].tv_sec = smb_fname->st.st_ex_atime.tv_sec; > times[0].tv_nsec = smb_fname->st.st_ex_atime.tv_nsec; >@@ -1252,26 +1418,39 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, > &smb_fname->st.st_ex_atime) == 0) && > (timespec_compare(×[1], > &smb_fname->st.st_ex_mtime) == 0)) { >+ END_PROFILE(syscall_ntimes); > return 0; > } > >- return glfs_utimens(handle->data, smb_fname->base_name, times); >+ ret = glfs_utimens(handle->data, smb_fname->base_name, times); >+ END_PROFILE(syscall_ntimes); >+ >+ return ret; > } > > static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle, > files_struct *fsp, off_t offset) > { >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ int ret; >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_ftruncate); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_ftruncate); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } > > #ifdef HAVE_GFAPI_VER_7_6 >- return glfs_ftruncate(glfd, offset, NULL, NULL); >+ ret = glfs_ftruncate(glfd, offset, NULL, NULL); > #else >- return glfs_ftruncate(glfd, offset); >+ ret = glfs_ftruncate(glfd, offset); > #endif >+ END_PROFILE(syscall_ftruncate); >+ >+ return ret; > } > > static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, >@@ -1279,10 +1458,16 @@ static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, > uint32_t mode, > off_t offset, off_t len) > { >+ int ret; > #ifdef HAVE_GFAPI_VER_6 >+ glfs_fd_t *glfd = NULL; > int keep_size, punch_hole; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ >+ START_PROFILE(syscall_fallocate); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_fallocate); > DBG_ERR("Failed to fetch gluster fd\n"); > return -1; > } >@@ -1292,19 +1477,22 @@ static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, > > mode &= ~(VFS_FALLOCATE_FL_KEEP_SIZE|VFS_FALLOCATE_FL_PUNCH_HOLE); > if (mode != 0) { >+ END_PROFILE(syscall_fallocate); > errno = ENOTSUP; > return -1; > } > > if (punch_hole) { >- return glfs_discard(glfd, offset, len); >+ ret = glfs_discard(glfd, offset, len); > } > >- return glfs_fallocate(glfd, keep_size, offset, len); >+ ret = glfs_fallocate(glfd, keep_size, offset, len); >+ END_PROFILE(syscall_fallocate); > #else > errno = ENOTSUP; >- return -1; >+ ret = -1; > #endif >+ return ret; > } > > static struct smb_filename *vfs_gluster_realpath(struct vfs_handle_struct *handle, >@@ -1313,9 +1501,13 @@ static struct smb_filename *vfs_gluster_realpath(struct vfs_handle_struct *handl > { > char *result = NULL; > struct smb_filename *result_fname = NULL; >- char *resolved_path = SMB_MALLOC_ARRAY(char, PATH_MAX+1); >+ char *resolved_path = NULL; > >+ START_PROFILE(syscall_realpath); >+ >+ resolved_path = SMB_MALLOC_ARRAY(char, PATH_MAX+1); > if (resolved_path == NULL) { >+ END_PROFILE(syscall_realpath); > errno = ENOMEM; > return NULL; > } >@@ -1328,6 +1520,8 @@ static struct smb_filename *vfs_gluster_realpath(struct vfs_handle_struct *handl > } > > SAFE_FREE(resolved_path); >+ END_PROFILE(syscall_realpath); >+ > return result_fname; > } > >@@ -1337,10 +1531,16 @@ static bool vfs_gluster_lock(struct vfs_handle_struct *handle, > { > struct flock flock = { 0, }; > int ret; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ glfs_fd_t *glfd = NULL; >+ bool ok = false; >+ >+ START_PROFILE(syscall_fcntl_lock); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { > DBG_ERR("Failed to fetch gluster fd\n"); >- return false; >+ ok = false; >+ goto out; > } > > flock.l_type = type; >@@ -1355,17 +1555,25 @@ static bool vfs_gluster_lock(struct vfs_handle_struct *handle, > /* lock query, true if someone else has locked */ > if ((ret != -1) && > (flock.l_type != F_UNLCK) && >- (flock.l_pid != 0) && (flock.l_pid != getpid())) >- return true; >+ (flock.l_pid != 0) && (flock.l_pid != getpid())) { >+ ok = true; >+ goto out; >+ } > /* not me */ >- return false; >+ ok = false; >+ goto out; > } > > if (ret == -1) { >- return false; >+ ok = false; >+ goto out; > } > >- return true; >+ ok = true; >+out: >+ END_PROFILE(syscall_fcntl_lock); >+ >+ return ok; > } > > static int vfs_gluster_kernel_flock(struct vfs_handle_struct *handle, >@@ -1389,8 +1597,13 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, > { > struct flock flock = { 0, }; > int ret; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ glfs_fd_t *glfd = NULL; >+ >+ START_PROFILE(syscall_fcntl_getlock); >+ >+ glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { >+ END_PROFILE(syscall_fcntl_getlock); > DBG_ERR("Failed to fetch gluster fd\n"); > return false; > } >@@ -1404,6 +1617,7 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, > ret = glfs_posix_lock(glfd, F_GETLK, &flock); > > if (ret == -1) { >+ END_PROFILE(syscall_fcntl_getlock); > return false; > } > >@@ -1411,6 +1625,7 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, > *poffset = flock.l_start; > *pcount = flock.l_len; > *ppid = flock.l_pid; >+ END_PROFILE(syscall_fcntl_getlock); > > return true; > } >@@ -1419,9 +1634,15 @@ static int vfs_gluster_symlink(struct vfs_handle_struct *handle, > const char *link_target, > const struct smb_filename *new_smb_fname) > { >- return glfs_symlink(handle->data, >+ int ret; >+ >+ START_PROFILE(syscall_symlink); >+ ret = glfs_symlink(handle->data, > link_target, > new_smb_fname->base_name); >+ END_PROFILE(syscall_symlink); >+ >+ return ret; > } > > static int vfs_gluster_readlink(struct vfs_handle_struct *handle, >@@ -1429,16 +1650,28 @@ static int vfs_gluster_readlink(struct vfs_handle_struct *handle, > char *buf, > size_t bufsiz) > { >- return glfs_readlink(handle->data, smb_fname->base_name, buf, bufsiz); >+ int ret; >+ >+ START_PROFILE(syscall_readlink); >+ ret = glfs_readlink(handle->data, smb_fname->base_name, buf, bufsiz); >+ END_PROFILE(syscall_readlink); >+ >+ return ret; > } > > static int vfs_gluster_link(struct vfs_handle_struct *handle, > const struct smb_filename *old_smb_fname, > const struct smb_filename *new_smb_fname) > { >- return glfs_link(handle->data, >+ int ret; >+ >+ START_PROFILE(syscall_link); >+ ret = glfs_link(handle->data, > old_smb_fname->base_name, > new_smb_fname->base_name); >+ END_PROFILE(syscall_link); >+ >+ return ret; > } > > static int vfs_gluster_mknod(struct vfs_handle_struct *handle, >@@ -1446,7 +1679,13 @@ static int vfs_gluster_mknod(struct vfs_handle_struct *handle, > mode_t mode, > SMB_DEV_T dev) > { >- return glfs_mknod(handle->data, smb_fname->base_name, mode, dev); >+ int ret; >+ >+ START_PROFILE(syscall_mknod); >+ ret = glfs_mknod(handle->data, smb_fname->base_name, mode, dev); >+ END_PROFILE(syscall_mknod); >+ >+ return ret; > } > > static int vfs_gluster_chflags(struct vfs_handle_struct *handle, >@@ -1505,7 +1744,7 @@ static ssize_t vfs_gluster_getxattr(struct vfs_handle_struct *handle, > size_t size) > { > return glfs_getxattr(handle->data, smb_fname->base_name, >- name, value, size); >+ name, value, size); > } > > static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle, >-- >2.17.1 > > >From d8ba147db50feeeedbeb738a2be24c28e3790a45 Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Sat, 18 May 2019 11:28:54 +0200 >Subject: [PATCH 086/376] vfs:glusterfs_fuse: ensure fileids are constant > across nodes >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Instead of adding a new gluster-specific mode to the fileid module, >this patches provides a fileid algorithm as part of the glusterfs_fuse >vfs module. This can not be configured further, simply adding the >glusterfs_fuse vfs module to the vfs objects configuration will enable >the new fileid mode. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13972 > >Signed-off-by: Michael Adam <obnox@samba.org> >Signed-off-by: Guenther Deschner <gd@samba.org> > >Autobuild-User(master): Günther Deschner <gd@samba.org> >Autobuild-Date(master): Sat Jul 13 22:54:56 UTC 2019 on sn-devel-184 > >(cherry picked from commit 5522aa1a4c34ee1a1e81db73cf41594bb10bd989) >--- > docs-xml/manpages/vfs_glusterfs_fuse.8.xml | 8 + > source3/modules/vfs_glusterfs_fuse.c | 193 ++++++++++++++++++++- > 2 files changed, 200 insertions(+), 1 deletion(-) > >diff --git a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >index b9f7f42c6f2..f2aa624353e 100644 >--- a/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >+++ b/docs-xml/manpages/vfs_glusterfs_fuse.8.xml >@@ -48,6 +48,14 @@ > case of an exisiting filename. > </para> > >+ <para> >+ Furthermore, this module implements a substitute file-id >+ mechanism. The default file-id mechanism is not working >+ correctly for gluster fuse mount re-exports, so in order to >+ avoid data loss, users exporting gluster fuse mounts with >+ Samba should enable this module. >+ </para> >+ > <para> > This module can be combined with other modules, but it > should be the last module in the <command>vfs objects</command> >diff --git a/source3/modules/vfs_glusterfs_fuse.c b/source3/modules/vfs_glusterfs_fuse.c >index 51515aa0df4..c621f9abf8e 100644 >--- a/source3/modules/vfs_glusterfs_fuse.c >+++ b/source3/modules/vfs_glusterfs_fuse.c >@@ -59,10 +59,201 @@ static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle, > return 0; > } > >+struct device_mapping_entry { >+ SMB_DEV_T device; /* the local device, for reference */ >+ uint64_t mapped_device; /* the mapped device */ >+}; >+ >+struct vfs_glusterfs_fuse_handle_data { >+ unsigned num_mapped_devices; >+ struct device_mapping_entry *mapped_devices; >+}; >+ >+/* a 64 bit hash, based on the one in tdb, copied from vfs_fileied */ >+static uint64_t vfs_glusterfs_fuse_uint64_hash(const uint8_t *s, size_t len) >+{ >+ uint64_t value; /* Used to compute the hash value. */ >+ uint32_t i; /* Used to cycle through random values. */ >+ >+ /* Set the initial value from the key size. */ >+ for (value = 0x238F13AFLL * len, i=0; i < len; i++) >+ value = (value + (((uint64_t)s[i]) << (i*5 % 24))); >+ >+ return (1103515243LL * value + 12345LL); >+} >+ >+static void vfs_glusterfs_fuse_load_devices( >+ struct vfs_glusterfs_fuse_handle_data *data) >+{ >+ FILE *f; >+ struct mntent *m; >+ >+ data->num_mapped_devices = 0; >+ TALLOC_FREE(data->mapped_devices); >+ >+ f = setmntent("/etc/mtab", "r"); >+ if (!f) { >+ return; >+ } >+ >+ while ((m = getmntent(f))) { >+ struct stat st; >+ char *p; >+ uint64_t mapped_device; >+ >+ if (stat(m->mnt_dir, &st) != 0) { >+ /* TODO: log? */ >+ continue; >+ } >+ >+ /* strip the host part off of the fsname */ >+ p = strrchr(m->mnt_fsname, ':'); >+ if (p == NULL) { >+ p = m->mnt_fsname; >+ } else { >+ /* TODO: consider the case of '' ? */ >+ p++; >+ } >+ >+ mapped_device = vfs_glusterfs_fuse_uint64_hash( >+ (const uint8_t *)p, >+ strlen(p)); >+ >+ data->mapped_devices = talloc_realloc(data, >+ data->mapped_devices, >+ struct device_mapping_entry, >+ data->num_mapped_devices + 1); >+ if (data->mapped_devices == NULL) { >+ goto nomem; >+ } >+ >+ data->mapped_devices[data->num_mapped_devices].device = >+ st.st_dev; >+ data->mapped_devices[data->num_mapped_devices].mapped_device = >+ mapped_device; >+ >+ data->num_mapped_devices++; >+ } >+ >+ endmntent(f); >+ return; >+ >+nomem: >+ data->num_mapped_devices = 0; >+ TALLOC_FREE(data->mapped_devices); >+ >+ endmntent(f); >+ return; >+} >+ >+static int vfs_glusterfs_fuse_map_device_cached( >+ struct vfs_glusterfs_fuse_handle_data *data, >+ SMB_DEV_T device, >+ uint64_t *mapped_device) >+{ >+ unsigned i; >+ >+ for (i = 0; i < data->num_mapped_devices; i++) { >+ if (data->mapped_devices[i].device == device) { >+ *mapped_device = data->mapped_devices[i].mapped_device; >+ return 0; >+ } >+ } >+ >+ return -1; >+} >+ >+static int vfs_glusterfs_fuse_map_device( >+ struct vfs_glusterfs_fuse_handle_data *data, >+ SMB_DEV_T device, >+ uint64_t *mapped_device) >+{ >+ int ret; >+ >+ ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device); >+ if (ret == 0) { >+ return 0; >+ } >+ >+ vfs_glusterfs_fuse_load_devices(data); >+ >+ ret = vfs_glusterfs_fuse_map_device_cached(data, device, mapped_device); >+ >+ return ret; >+} >+ >+static struct file_id vfs_glusterfs_fuse_file_id_create( >+ struct vfs_handle_struct *handle, >+ const SMB_STRUCT_STAT *sbuf) >+{ >+ struct vfs_glusterfs_fuse_handle_data *data; >+ struct file_id id; >+ uint64_t mapped_device; >+ int ret; >+ >+ ZERO_STRUCT(id); >+ >+ id = SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf); >+ >+ SMB_VFS_HANDLE_GET_DATA(handle, data, >+ struct vfs_glusterfs_fuse_handle_data, >+ return id); >+ >+ ret = vfs_glusterfs_fuse_map_device(data, sbuf->st_ex_dev, >+ &mapped_device); >+ if (ret == 0) { >+ id.devid = mapped_device; >+ } else { >+ DBG_WARNING("Failed to map device [%jx], falling back to " >+ "standard file_id [%jx]", >+ (uintmax_t)sbuf->st_ex_dev, >+ (uintmax_t)id.devid); >+ } >+ >+ DBG_DEBUG("Returning dev [%jx] inode [%jx]\n", >+ (uintmax_t)id.devid, (uintmax_t)id.inode); >+ >+ return id; >+} >+ >+static int vfs_glusterfs_fuse_connect(struct vfs_handle_struct *handle, >+ const char *service, const char *user) >+{ >+ struct vfs_glusterfs_fuse_handle_data *data; >+ int ret = SMB_VFS_NEXT_CONNECT(handle, service, user); >+ >+ if (ret < 0) { >+ return ret; >+ } >+ >+ data = talloc_zero(handle->conn, struct vfs_glusterfs_fuse_handle_data); >+ if (data == NULL) { >+ DBG_ERR("talloc_zero() failed.\n"); >+ SMB_VFS_NEXT_DISCONNECT(handle); >+ return -1; >+ } >+ >+ /* >+ * Fill the cache in the tree connect, so that the first file/dir access >+ * has chances of being fast... >+ */ >+ vfs_glusterfs_fuse_load_devices(data); >+ >+ SMB_VFS_HANDLE_SET_DATA(handle, data, NULL, >+ struct vfs_glusterfs_fuse_handle_data, >+ return -1); >+ >+ DBG_DEBUG("vfs_glusterfs_fuse_connect(): connected to service[%s]\n", >+ service); >+ >+ return 0; >+} >+ > struct vfs_fn_pointers glusterfs_fuse_fns = { > >- /* File Operations */ >+ .connect_fn = vfs_glusterfs_fuse_connect, > .get_real_filename_fn = vfs_gluster_fuse_get_real_filename, >+ .file_id_create_fn = vfs_glusterfs_fuse_file_id_create, > }; > > static_decl_vfs; >-- >2.17.1 > > >From 53b0fd2216dfd93ae0379f48e712294137e9b5b6 Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Thu, 1 Aug 2019 00:47:29 +0200 >Subject: [PATCH 087/376] vfs:glusterfs_fuse: build only if we have setmntent() > >FreeBSD and other platforms that don't have setmntent() and friends can >not compile this module. This patch lets changes the build to only >compile this module if the setmntent() function is found. > >This is the a follow-up fix to the actual fix for bug #13972. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13972 > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Amitay Isaacs <amitay@samba.org> >Autobuild-Date(master): Thu Aug 1 09:49:04 UTC 2019 on sn-devel-184 > >(cherry picked from commit f258cfaa1d07af6ac6e996006f6e59955cfe34ce) >--- > source3/wscript | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/source3/wscript b/source3/wscript >index ff72a173a4b..4a3e75605e7 100644 >--- a/source3/wscript >+++ b/source3/wscript >@@ -1713,7 +1713,6 @@ main() { > vfs_media_harmony vfs_unityed_media vfs_fruit vfs_shell_snap > vfs_commit vfs_worm vfs_crossrename vfs_linux_xfs_sgid > vfs_time_audit vfs_offline vfs_virusfilter >- vfs_glusterfs_fuse > ''')) > default_shared_modules.extend(TO_LIST('auth_script idmap_tdb2 idmap_script')) > # these have broken dependencies >@@ -1775,6 +1774,9 @@ main() { > if conf.CONFIG_SET('HAVE_GLUSTERFS'): > default_shared_modules.extend(TO_LIST('vfs_glusterfs')) > >+ if conf.CONFIG_SET('HAVE_SETMNTENT'): >+ default_shared_modules.extend(TO_LIST('vfs_glusterfs_fuse')) >+ > if conf.CONFIG_SET('HAVE_VXFS'): > default_shared_modules.extend(TO_LIST('vfs_vxfs')) > >-- >2.17.1 > > >From 0b4a99c22f5e72d2bc6e2770b070e964866db148 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Thu, 8 Aug 2019 16:20:44 +1000 >Subject: [PATCH 088/376] ctdb-daemon: Add function ctdb_ip_to_node() > >This is the core logic from ctdb_ip_to_pnn(), so re-implement that >that function using ctdb_ip_to_node(). > >Something similar (ctdb_ip_to_nodeid()) was recently removed in commit >010c1d77cd7e192b1fff39b7b91fccbdbbf4a786 because it wasn't required. >Now there is a use case. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 3acb8e9d1c854b577d6be282257269df83055d31) >--- > ctdb/include/ctdb_private.h | 2 ++ > ctdb/server/ctdb_server.c | 24 +++++++++++++++++++----- > 2 files changed, 21 insertions(+), 5 deletions(-) > >diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h >index 2bcc7c94156..1e9619faddf 100644 >--- a/ctdb/include/ctdb_private.h >+++ b/ctdb/include/ctdb_private.h >@@ -831,6 +831,8 @@ void ctdb_stop_recoverd(struct ctdb_context *ctdb); > > int ctdb_set_transport(struct ctdb_context *ctdb, const char *transport); > >+struct ctdb_node *ctdb_ip_to_node(struct ctdb_context *ctdb, >+ const ctdb_sock_addr *nodeip); > uint32_t ctdb_ip_to_pnn(struct ctdb_context *ctdb, > const ctdb_sock_addr *nodeip); > >diff --git a/ctdb/server/ctdb_server.c b/ctdb/server/ctdb_server.c >index dcd761a2961..9724d1fe0a8 100644 >--- a/ctdb/server/ctdb_server.c >+++ b/ctdb/server/ctdb_server.c >@@ -45,9 +45,9 @@ int ctdb_set_transport(struct ctdb_context *ctdb, const char *transport) > return 0; > } > >-/* Return the PNN for nodeip, CTDB_UNKNOWN_PNN if nodeip is invalid */ >-uint32_t ctdb_ip_to_pnn(struct ctdb_context *ctdb, >- const ctdb_sock_addr *nodeip) >+/* Return the node structure for nodeip, NULL if nodeip is invalid */ >+struct ctdb_node *ctdb_ip_to_node(struct ctdb_context *ctdb, >+ const ctdb_sock_addr *nodeip) > { > unsigned int nodeid; > >@@ -56,11 +56,25 @@ uint32_t ctdb_ip_to_pnn(struct ctdb_context *ctdb, > continue; > } > if (ctdb_same_ip(&ctdb->nodes[nodeid]->address, nodeip)) { >- return ctdb->nodes[nodeid]->pnn; >+ return ctdb->nodes[nodeid]; > } > } > >- return CTDB_UNKNOWN_PNN; >+ return NULL; >+} >+ >+/* Return the PNN for nodeip, CTDB_UNKNOWN_PNN if nodeip is invalid */ >+uint32_t ctdb_ip_to_pnn(struct ctdb_context *ctdb, >+ const ctdb_sock_addr *nodeip) >+{ >+ struct ctdb_node *node; >+ >+ node = ctdb_ip_to_node(ctdb, nodeip); >+ if (node == NULL) { >+ return CTDB_UNKNOWN_PNN; >+ } >+ >+ return node->pnn; > } > > /* Load a nodes list file into a nodes array */ >-- >2.17.1 > > >From 4cf26ff2ec350db6b3ad5fa08dea602b3b842baf Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Fri, 9 Aug 2019 15:06:34 +1000 >Subject: [PATCH 089/376] ctdb-tcp: Rename fd -> out_fd > >in_fd is coming soon. > >Fix coding style violations in the affected and adjacent lines. >Modernise some debug macros and make them more consistent (e.g. drop >logging of errno when strerror(errno) is already logged. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit c06620169fc178ea6db2631f03edf008285d8cf2) >--- > ctdb/tcp/ctdb_tcp.h | 2 +- > ctdb/tcp/tcp_connect.c | 97 +++++++++++++++++++++++++----------------- > ctdb/tcp/tcp_init.c | 22 ++++++---- > 3 files changed, 72 insertions(+), 49 deletions(-) > >diff --git a/ctdb/tcp/ctdb_tcp.h b/ctdb/tcp/ctdb_tcp.h >index 0a998c94da4..acd343fb8f3 100644 >--- a/ctdb/tcp/ctdb_tcp.h >+++ b/ctdb/tcp/ctdb_tcp.h >@@ -39,7 +39,7 @@ struct ctdb_incoming { > state associated with one tcp node > */ > struct ctdb_tcp_node { >- int fd; >+ int out_fd; > struct ctdb_queue *out_queue; > struct tevent_fd *connect_fde; > struct tevent_timer *connect_te; >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index d757abdf26c..4253f3bef7c 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -50,9 +50,9 @@ void ctdb_tcp_stop_connection(struct ctdb_node *node) > talloc_free(tnode->connect_fde); > tnode->connect_fde = NULL; > tnode->connect_te = NULL; >- if (tnode->fd != -1) { >- close(tnode->fd); >- tnode->fd = -1; >+ if (tnode->out_fd != -1) { >+ close(tnode->out_fd); >+ tnode->out_fd = -1; > } > } > >@@ -93,12 +93,13 @@ static void ctdb_node_connect_write(struct tevent_context *ev, > int error = 0; > socklen_t len = sizeof(error); > int one = 1; >+ int ret; > > talloc_free(tnode->connect_te); > tnode->connect_te = NULL; > >- if (getsockopt(tnode->fd, SOL_SOCKET, SO_ERROR, &error, &len) != 0 || >- error != 0) { >+ ret = getsockopt(tnode->out_fd, SOL_SOCKET, SO_ERROR, &error, &len); >+ if (ret != 0 || error != 0) { > ctdb_tcp_stop_connection(node); > tnode->connect_te = tevent_add_timer(ctdb->ev, tnode, > timeval_current_ofs(1, 0), >@@ -109,19 +110,28 @@ static void ctdb_node_connect_write(struct tevent_context *ev, > talloc_free(tnode->connect_fde); > tnode->connect_fde = NULL; > >- if (setsockopt(tnode->fd,IPPROTO_TCP,TCP_NODELAY,(char *)&one,sizeof(one)) == -1) { >- DEBUG(DEBUG_WARNING, ("Failed to set TCP_NODELAY on fd - %s\n", >- strerror(errno))); >+ ret = setsockopt(tnode->out_fd, >+ IPPROTO_TCP, >+ TCP_NODELAY, >+ (char *)&one, >+ sizeof(one)); >+ if (ret == -1) { >+ DBG_WARNING("Failed to set TCP_NODELAY on fd - %s\n", >+ strerror(errno)); > } >- if (setsockopt(tnode->fd,SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(one)) == -1) { >- DEBUG(DEBUG_WARNING, ("Failed to set KEEPALIVE on fd - %s\n", >- strerror(errno))); >+ ret = setsockopt(tnode->out_fd, >+ SOL_SOCKET, >+ SO_KEEPALIVE,(char *)&one, >+ sizeof(one)); >+ if (ret == -1) { >+ DBG_WARNING("Failed to set KEEPALIVE on fd - %s\n", >+ strerror(errno)); > } > >- ctdb_queue_set_fd(tnode->out_queue, tnode->fd); >+ ctdb_queue_set_fd(tnode->out_queue, tnode->out_fd); > > /* the queue subsystem now owns this fd */ >- tnode->fd = -1; >+ tnode->out_fd = -1; > > /* tell the ctdb layer we are connected */ > node->ctdb->upcalls->node_connected(node); >@@ -149,26 +159,24 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te, > > sock_out = node->address; > >- tnode->fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); >- if (tnode->fd == -1) { >- DEBUG(DEBUG_ERR, (__location__ " Failed to create socket\n")); >+ tnode->out_fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); >+ if (tnode->out_fd == -1) { >+ DBG_ERR("Failed to create socket\n"); > return; > } > >- ret = set_blocking(tnode->fd, false); >+ ret = set_blocking(tnode->out_fd, false); > if (ret != 0) { >- DEBUG(DEBUG_ERR, >- (__location__ >- " failed to set socket non-blocking (%s)\n", >- strerror(errno))); >- close(tnode->fd); >- tnode->fd = -1; >+ DBG_ERR("Failed to set socket non-blocking (%s)\n", >+ strerror(errno)); >+ close(tnode->out_fd); >+ tnode->out_fd = -1; > return; > } > >- set_close_on_exec(tnode->fd); >+ set_close_on_exec(tnode->out_fd); > >- DEBUG(DEBUG_DEBUG, (__location__ " Created TCP SOCKET FD:%d\n", tnode->fd)); >+ DBG_DEBUG("Created TCP SOCKET FD:%d\n", tnode->out_fd); > > /* Bind our side of the socketpair to the same address we use to listen > * on incoming CTDB traffic. >@@ -197,39 +205,48 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te, > default: > DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n", > sock_in.sa.sa_family)); >- close(tnode->fd); >- tnode->fd = -1; >+ close(tnode->out_fd); >+ tnode->out_fd = -1; > return; > } > >- if (bind(tnode->fd, (struct sockaddr *)&sock_in, sockin_size) == -1) { >- DEBUG(DEBUG_ERR, (__location__ " Failed to bind socket %s(%d)\n", >- strerror(errno), errno)); >- close(tnode->fd); >- tnode->fd = -1; >+ ret = bind(tnode->out_fd, (struct sockaddr *)&sock_in, sockin_size); >+ if (ret == -1) { >+ DBG_ERR("Failed to bind socket (%s)\n", strerror(errno)); >+ close(tnode->out_fd); >+ tnode->out_fd = -1; > return; > } > >- if (connect(tnode->fd, (struct sockaddr *)&sock_out, sockout_size) != 0 && >- errno != EINPROGRESS) { >+ ret = connect(tnode->out_fd, >+ (struct sockaddr *)&sock_out, >+ sockout_size); >+ if (ret != 0 && errno != EINPROGRESS) { > ctdb_tcp_stop_connection(node); >- tnode->connect_te = tevent_add_timer(ctdb->ev, tnode, >+ tnode->connect_te = tevent_add_timer(ctdb->ev, >+ tnode, > timeval_current_ofs(1, 0), >- ctdb_tcp_node_connect, node); >+ ctdb_tcp_node_connect, >+ node); > return; > } > > /* non-blocking connect - wait for write event */ >- tnode->connect_fde = tevent_add_fd(node->ctdb->ev, tnode, tnode->fd, >+ tnode->connect_fde = tevent_add_fd(node->ctdb->ev, >+ tnode, >+ tnode->out_fd, > TEVENT_FD_WRITE|TEVENT_FD_READ, >- ctdb_node_connect_write, node); >+ ctdb_node_connect_write, >+ node); > > /* don't give it long to connect - retry in one second. This ensures > that we find a node is up quickly (tcp normally backs off a syn reply > delay by quite a lot) */ >- tnode->connect_te = tevent_add_timer(ctdb->ev, tnode, >+ tnode->connect_te = tevent_add_timer(ctdb->ev, >+ tnode, > timeval_current_ofs(1, 0), >- ctdb_tcp_node_connect, node); >+ ctdb_tcp_node_connect, >+ node); > } > > /* >diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c >index 87d628aba93..6b1299f32b5 100644 >--- a/ctdb/tcp/tcp_init.c >+++ b/ctdb/tcp/tcp_init.c >@@ -38,16 +38,16 @@ static int tnode_destructor(struct ctdb_tcp_node *tnode) > { > // struct ctdb_node *node = talloc_find_parent_bytype(tnode, struct ctdb_node); > >- if (tnode->fd != -1) { >- close(tnode->fd); >- tnode->fd = -1; >+ if (tnode->out_fd != -1) { >+ close(tnode->out_fd); >+ tnode->out_fd = -1; > } > > return 0; > } > > /* >- initialise tcp portion of a ctdb node >+ initialise tcp portion of a ctdb node > */ > static int ctdb_tcp_add_node(struct ctdb_node *node) > { >@@ -55,13 +55,19 @@ static int ctdb_tcp_add_node(struct ctdb_node *node) > tnode = talloc_zero(node, struct ctdb_tcp_node); > CTDB_NO_MEMORY(node->ctdb, tnode); > >- tnode->fd = -1; >+ tnode->out_fd = -1; > node->private_data = tnode; > talloc_set_destructor(tnode, tnode_destructor); > >- tnode->out_queue = ctdb_queue_setup(node->ctdb, node, tnode->fd, CTDB_TCP_ALIGNMENT, >- ctdb_tcp_tnode_cb, node, "to-node-%s", node->name); >- >+ tnode->out_queue = ctdb_queue_setup(node->ctdb, >+ node, >+ tnode->out_fd, >+ CTDB_TCP_ALIGNMENT, >+ ctdb_tcp_tnode_cb, >+ node, >+ "to-node-%s", >+ node->name); >+ > return 0; > } > >-- >2.17.1 > > >From bf39d0cff16cd240ceddb3cb88183ad61e667ac2 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Fri, 9 Aug 2019 15:29:36 +1000 >Subject: [PATCH 090/376] ctdb-tcp: Move incoming fd and queue into struct > ctdb_tcp_node > >This makes it easy to track both incoming and outgoing connectivity >states. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit c68b6f96f26664459187ab2fbd56767fb31767e0) >--- > ctdb/tcp/ctdb_tcp.h | 14 ++++----- > ctdb/tcp/tcp_connect.c | 64 +++++++++++++++++++++++++++--------------- > ctdb/tcp/tcp_init.c | 8 ++++++ > ctdb/tcp/tcp_io.c | 9 ++++-- > 4 files changed, 61 insertions(+), 34 deletions(-) > >diff --git a/ctdb/tcp/ctdb_tcp.h b/ctdb/tcp/ctdb_tcp.h >index acd343fb8f3..9a615fc6393 100644 >--- a/ctdb/tcp/ctdb_tcp.h >+++ b/ctdb/tcp/ctdb_tcp.h >@@ -26,23 +26,19 @@ struct ctdb_tcp { > int listen_fd; > }; > >-/* >- state associated with an incoming connection >-*/ >-struct ctdb_incoming { >- struct ctdb_context *ctdb; >- int fd; >- struct ctdb_queue *queue; >-}; >- > /* > state associated with one tcp node > */ > struct ctdb_tcp_node { > int out_fd; > struct ctdb_queue *out_queue; >+ > struct tevent_fd *connect_fde; > struct tevent_timer *connect_te; >+ >+ struct ctdb_context *ctdb; >+ int in_fd; >+ struct ctdb_queue *in_queue; > }; > > >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index 4253f3bef7c..866454f3d29 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -262,8 +262,8 @@ static void ctdb_listen_event(struct tevent_context *ev, struct tevent_fd *fde, > ctdb_sock_addr addr; > socklen_t len; > int fd; >- uint32_t pnn; >- struct ctdb_incoming *in; >+ struct ctdb_node *node; >+ struct ctdb_tcp_node *tnode; > int one = 1; > int ret; > >@@ -273,41 +273,61 @@ static void ctdb_listen_event(struct tevent_context *ev, struct tevent_fd *fde, > if (fd == -1) return; > smb_set_close_on_exec(fd); > >- pnn = ctdb_ip_to_pnn(ctdb, &addr); >- >- if (pnn == CTDB_UNKNOWN_PNN) { >+ node = ctdb_ip_to_node(ctdb, &addr); >+ if (node == NULL) { > D_ERR("Refused connection from unknown node %s\n", > ctdb_addr_to_str(&addr)); > close(fd); > return; > } > >- in = talloc_zero(ctcp, struct ctdb_incoming); >- in->fd = fd; >- in->ctdb = ctdb; >+ tnode = talloc_get_type_abort(node->private_data, >+ struct ctdb_tcp_node); >+ if (tnode == NULL) { >+ /* This can't happen - see ctdb_tcp_initialise() */ >+ DBG_ERR("INTERNAL ERROR setting up connection from node %s\n", >+ ctdb_addr_to_str(&addr)); >+ close(fd); >+ return; >+ } > >- ret = set_blocking(in->fd, false); >+ ret = set_blocking(fd, false); > if (ret != 0) { >- DEBUG(DEBUG_ERR, >- (__location__ >- " failed to set socket non-blocking (%s)\n", >- strerror(errno))); >- close(in->fd); >- in->fd = -1; >+ DBG_ERR("Failed to set socket non-blocking (%s)\n", >+ strerror(errno)); >+ close(fd); > return; > } > >- set_close_on_exec(in->fd); >+ set_close_on_exec(fd); > >- DEBUG(DEBUG_DEBUG, (__location__ " Created SOCKET FD:%d to incoming ctdb connection\n", fd)); >+ DBG_DEBUG("Created SOCKET FD:%d to incoming ctdb connection\n", fd); > >- if (setsockopt(in->fd,SOL_SOCKET,SO_KEEPALIVE,(char *)&one,sizeof(one)) == -1) { >- DEBUG(DEBUG_WARNING, ("Failed to set KEEPALIVE on fd - %s\n", >- strerror(errno))); >+ ret = setsockopt(fd, >+ SOL_SOCKET, >+ SO_KEEPALIVE, >+ (char *)&one, >+ sizeof(one)); >+ if (ret == -1) { >+ DBG_WARNING("Failed to set KEEPALIVE on fd - %s\n", >+ strerror(errno)); >+ } >+ >+ tnode->in_queue = ctdb_queue_setup(ctdb, >+ tnode, >+ fd, >+ CTDB_TCP_ALIGNMENT, >+ ctdb_tcp_read_cb, >+ tnode, >+ "ctdbd-%s", >+ ctdb_addr_to_str(&addr)); >+ if (tnode->in_queue == NULL) { >+ DBG_ERR("Failed to set up incoming queue\n"); >+ close(fd); >+ return; > } > >- in->queue = ctdb_queue_setup(ctdb, in, in->fd, CTDB_TCP_ALIGNMENT, >- ctdb_tcp_read_cb, in, "ctdbd-%s", ctdb_addr_to_str(&addr)); >+ tnode->in_fd = fd; > } > > >diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c >index 6b1299f32b5..d4b42b0d0f2 100644 >--- a/ctdb/tcp/tcp_init.c >+++ b/ctdb/tcp/tcp_init.c >@@ -43,6 +43,11 @@ static int tnode_destructor(struct ctdb_tcp_node *tnode) > tnode->out_fd = -1; > } > >+ if (tnode->in_fd != -1) { >+ close(tnode->in_fd); >+ tnode->in_fd = -1; >+ } >+ > return 0; > } > >@@ -56,6 +61,9 @@ static int ctdb_tcp_add_node(struct ctdb_node *node) > CTDB_NO_MEMORY(node->ctdb, tnode); > > tnode->out_fd = -1; >+ tnode->in_fd = -1; >+ tnode->ctdb = node->ctdb; >+ > node->private_data = tnode; > talloc_set_destructor(tnode, tnode_destructor); > >diff --git a/ctdb/tcp/tcp_io.c b/ctdb/tcp/tcp_io.c >index 0eb8e25eea3..be4558b16ea 100644 >--- a/ctdb/tcp/tcp_io.c >+++ b/ctdb/tcp/tcp_io.c >@@ -37,7 +37,8 @@ > */ > void ctdb_tcp_read_cb(uint8_t *data, size_t cnt, void *args) > { >- struct ctdb_incoming *in = talloc_get_type(args, struct ctdb_incoming); >+ struct ctdb_tcp_node *tnode = talloc_get_type_abort( >+ args, struct ctdb_tcp_node); > struct ctdb_req_header *hdr = (struct ctdb_req_header *)data; > > if (data == NULL) { >@@ -69,11 +70,13 @@ void ctdb_tcp_read_cb(uint8_t *data, size_t cnt, void *args) > } > > /* tell the ctdb layer above that we have a packet */ >- in->ctdb->upcalls->recv_pkt(in->ctdb, data, cnt); >+ tnode->ctdb->upcalls->recv_pkt(tnode->ctdb, data, cnt); > return; > > failed: >- TALLOC_FREE(in); >+ TALLOC_FREE(tnode->in_queue); >+ close(tnode->in_fd); >+ tnode->in_fd = -1; > TALLOC_FREE(data); > } > >-- >2.17.1 > > >From 1ef2ffbab865b80c90a69b5899285c0b7409c26d Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Thu, 15 Aug 2019 15:45:16 +1000 >Subject: [PATCH 091/376] ctdb-tcp: Use TALLOC_FREE() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit d80d9edb4dc107b15a35a39e5c966a3eaed6453a) >--- > ctdb/tcp/tcp_connect.c | 6 ++---- > 1 file changed, 2 insertions(+), 4 deletions(-) > >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index 866454f3d29..16d75481050 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -46,10 +46,8 @@ void ctdb_tcp_stop_connection(struct ctdb_node *node) > node->private_data, struct ctdb_tcp_node); > > ctdb_queue_set_fd(tnode->out_queue, -1); >- talloc_free(tnode->connect_te); >- talloc_free(tnode->connect_fde); >- tnode->connect_fde = NULL; >- tnode->connect_te = NULL; >+ TALLOC_FREE(tnode->connect_te); >+ TALLOC_FREE(tnode->connect_fde); > if (tnode->out_fd != -1) { > close(tnode->out_fd); > tnode->out_fd = -1; >-- >2.17.1 > > >From 6668733c306896a779c707acdd9912efcf52c0da Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Thu, 15 Aug 2019 15:57:31 +1000 >Subject: [PATCH 092/376] ctdb-tcp: Create outbound queue when the connection > becomes writable > >Since commit ddd97553f0a8bfaada178ec4a7460d76fa21f079 >ctdb_queue_send() doesn't queue a packet if the connection isn't yet >established (i.e. when fd == -1). So, don't bother creating the >outbound queue during initialisation but create it when the connection >becomes writable. > >Now the presence of the queue indicates that the outbound connection >is up. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 7f4854d9643a096a6d8a354fcd27b7c6ed24a75e) >--- > ctdb/tcp/tcp_connect.c | 23 ++++++++++++++++++++--- > ctdb/tcp/tcp_init.c | 9 --------- > ctdb/tcp/tcp_io.c | 5 +++++ > 3 files changed, 25 insertions(+), 12 deletions(-) > >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index 16d75481050..4374242015c 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -44,8 +44,8 @@ void ctdb_tcp_stop_connection(struct ctdb_node *node) > { > struct ctdb_tcp_node *tnode = talloc_get_type( > node->private_data, struct ctdb_tcp_node); >- >- ctdb_queue_set_fd(tnode->out_queue, -1); >+ >+ TALLOC_FREE(tnode->out_queue); > TALLOC_FREE(tnode->connect_te); > TALLOC_FREE(tnode->connect_fde); > if (tnode->out_fd != -1) { >@@ -126,7 +126,24 @@ static void ctdb_node_connect_write(struct tevent_context *ev, > strerror(errno)); > } > >- ctdb_queue_set_fd(tnode->out_queue, tnode->out_fd); >+ tnode->out_queue = ctdb_queue_setup(node->ctdb, >+ tnode, >+ tnode->out_fd, >+ CTDB_TCP_ALIGNMENT, >+ ctdb_tcp_tnode_cb, >+ node, >+ "to-node-%s", >+ node->name); >+ if (tnode->out_queue == NULL) { >+ DBG_ERR("Failed to set up outgoing queue\n"); >+ ctdb_tcp_stop_connection(node); >+ tnode->connect_te = tevent_add_timer(ctdb->ev, >+ tnode, >+ timeval_current_ofs(1, 0), >+ ctdb_tcp_node_connect, >+ node); >+ return; >+ } > > /* the queue subsystem now owns this fd */ > tnode->out_fd = -1; >diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c >index d4b42b0d0f2..a9cb9b36a01 100644 >--- a/ctdb/tcp/tcp_init.c >+++ b/ctdb/tcp/tcp_init.c >@@ -67,15 +67,6 @@ static int ctdb_tcp_add_node(struct ctdb_node *node) > node->private_data = tnode; > talloc_set_destructor(tnode, tnode_destructor); > >- tnode->out_queue = ctdb_queue_setup(node->ctdb, >- node, >- tnode->out_fd, >- CTDB_TCP_ALIGNMENT, >- ctdb_tcp_tnode_cb, >- node, >- "to-node-%s", >- node->name); >- > return 0; > } > >diff --git a/ctdb/tcp/tcp_io.c b/ctdb/tcp/tcp_io.c >index be4558b16ea..e33ed44048e 100644 >--- a/ctdb/tcp/tcp_io.c >+++ b/ctdb/tcp/tcp_io.c >@@ -87,5 +87,10 @@ int ctdb_tcp_queue_pkt(struct ctdb_node *node, uint8_t *data, uint32_t length) > { > struct ctdb_tcp_node *tnode = talloc_get_type(node->private_data, > struct ctdb_tcp_node); >+ if (tnode->out_queue == NULL) { >+ DBG_DEBUG("No outgoing connection, dropping packet\n"); >+ return 0; >+ } >+ > return ctdb_queue_send(tnode->out_queue, data, length); > } >-- >2.17.1 > > >From adb19f17cd1a778a6ee58d7f4658b9f27ea087de Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Fri, 9 Aug 2019 15:33:05 +1000 >Subject: [PATCH 093/376] ctdb-tcp: Only mark a node connected if both > directions are up > >Nodes are currently marked as up if the outgoing connection is >established. However, if the incoming connection is not yet >established then this node could send a request where the replying >node can not queue its reply. Wait until both directions are up >before marking a node as connected. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 8c98c10f242bc722beffc711e85c0e4f2e74cd57) >--- > ctdb/tcp/tcp_connect.c | 20 +++++++++++++++++--- > 1 file changed, 17 insertions(+), 3 deletions(-) > >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index 4374242015c..fd635b9abf2 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -148,8 +148,14 @@ static void ctdb_node_connect_write(struct tevent_context *ev, > /* the queue subsystem now owns this fd */ > tnode->out_fd = -1; > >- /* tell the ctdb layer we are connected */ >- node->ctdb->upcalls->node_connected(node); >+ /* >+ * Mark the node to which this connection has been established >+ * as connected, but only if the corresponding listening >+ * socket is also connected >+ */ >+ if (tnode->in_fd != -1) { >+ node->ctdb->upcalls->node_connected(node); >+ } > } > > >@@ -343,7 +349,15 @@ static void ctdb_listen_event(struct tevent_context *ev, struct tevent_fd *fde, > } > > tnode->in_fd = fd; >-} >+ >+ /* >+ * Mark the connecting node as connected, but only if the >+ * corresponding outbound connected is also up >+ */ >+ if (tnode->out_queue != NULL) { >+ node->ctdb->upcalls->node_connected(node); >+ } >+ } > > > /* >-- >2.17.1 > > >From 240ad91944d617d33b85aaeeed2a57ecf1ce9c67 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Tue, 13 Aug 2019 17:08:43 +1000 >Subject: [PATCH 094/376] ctdb-tcp: Mark node as disconnected if incoming > connection goes away > >To make it easy to pass the node data to the upcall, the private data >for ctdb_tcp_read_cb() needs to be changed from tnode to node. > >RN: Avoid marking a node as connected before it can receive packets >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14084 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Martin Schwenke <martins@samba.org> >Autobuild-Date(master): Fri Aug 16 22:50:35 UTC 2019 on sn-devel-184 > >(cherry picked from commit 73c850eda4209b688a169aeeb20c453b738cbb35) >--- > ctdb/tcp/tcp_connect.c | 2 +- > ctdb/tcp/tcp_io.c | 5 ++++- > 2 files changed, 5 insertions(+), 2 deletions(-) > >diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c >index fd635b9abf2..6123380ca9f 100644 >--- a/ctdb/tcp/tcp_connect.c >+++ b/ctdb/tcp/tcp_connect.c >@@ -339,7 +339,7 @@ static void ctdb_listen_event(struct tevent_context *ev, struct tevent_fd *fde, > fd, > CTDB_TCP_ALIGNMENT, > ctdb_tcp_read_cb, >- tnode, >+ node, > "ctdbd-%s", > ctdb_addr_to_str(&addr)); > if (tnode->in_queue == NULL) { >diff --git a/ctdb/tcp/tcp_io.c b/ctdb/tcp/tcp_io.c >index e33ed44048e..e8ebff887e1 100644 >--- a/ctdb/tcp/tcp_io.c >+++ b/ctdb/tcp/tcp_io.c >@@ -37,8 +37,9 @@ > */ > void ctdb_tcp_read_cb(uint8_t *data, size_t cnt, void *args) > { >+ struct ctdb_node *node = talloc_get_type_abort(args, struct ctdb_node); > struct ctdb_tcp_node *tnode = talloc_get_type_abort( >- args, struct ctdb_tcp_node); >+ node->private_data, struct ctdb_tcp_node); > struct ctdb_req_header *hdr = (struct ctdb_req_header *)data; > > if (data == NULL) { >@@ -77,6 +78,8 @@ failed: > TALLOC_FREE(tnode->in_queue); > close(tnode->in_fd); > tnode->in_fd = -1; >+ node->ctdb->upcalls->node_dead(node); >+ > TALLOC_FREE(data); > } > >-- >2.17.1 > > >From 093973899580c2fd1a95d067ff695388b7bdc4f8 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 19 Aug 2019 21:47:03 +1000 >Subject: [PATCH 095/376] ctdb-daemon: Factor out new function > ctdb_node_become_inactive() > >This is a superset of ctdb_local_node_got_banned() so will replace >that function, and will also be used in the NODE_STOP control. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14087 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit a42bcaabb63722411bee52b80cbfc795593defbc) >--- > ctdb/include/ctdb_private.h | 2 ++ > ctdb/server/ctdb_recover.c | 43 +++++++++++++++++++++++++++++++++++++ > 2 files changed, 45 insertions(+) > >diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h >index 1e9619faddf..d9d13fad358 100644 >--- a/ctdb/include/ctdb_private.h >+++ b/ctdb/include/ctdb_private.h >@@ -819,6 +819,8 @@ int32_t ctdb_control_recd_ping(struct ctdb_context *ctdb); > int32_t ctdb_control_set_recmaster(struct ctdb_context *ctdb, > uint32_t opcode, TDB_DATA indata); > >+void ctdb_node_become_inactive(struct ctdb_context *ctdb); >+ > int32_t ctdb_control_stop_node(struct ctdb_context *ctdb); > int32_t ctdb_control_continue_node(struct ctdb_context *ctdb); > >diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c >index 343728839c1..df60a4cb9c0 100644 >--- a/ctdb/server/ctdb_recover.c >+++ b/ctdb/server/ctdb_recover.c >@@ -1420,6 +1420,49 @@ int32_t ctdb_control_set_recmaster(struct ctdb_context *ctdb, uint32_t opcode, T > return 0; > } > >+void ctdb_node_become_inactive(struct ctdb_context *ctdb) >+{ >+ struct ctdb_db_context *ctdb_db; >+ >+ D_WARNING("Making node INACTIVE\n"); >+ >+ /* >+ * Do not service database calls - reset generation to invalid >+ * so this node ignores any REQ/REPLY CALL/DMASTER >+ */ >+ ctdb->vnn_map->generation = INVALID_GENERATION; >+ for (ctdb_db = ctdb->db_list; ctdb_db != NULL; ctdb_db = ctdb_db->next) { >+ ctdb_db->generation = INVALID_GENERATION; >+ } >+ >+ /* >+ * Although this bypasses the control, the only thing missing >+ * is the deferred drop of all public IPs, which isn't >+ * necessary because they are dropped below >+ */ >+ if (ctdb->recovery_mode != CTDB_RECOVERY_ACTIVE) { >+ D_NOTICE("Recovery mode set to ACTIVE\n"); >+ ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE; >+ } >+ >+ /* >+ * Initiate database freeze - this will be scheduled for >+ * immediate execution and will be in progress long before the >+ * calling control returns >+ */ >+ ctdb_daemon_send_control(ctdb, >+ ctdb->pnn, >+ 0, >+ CTDB_CONTROL_FREEZE, >+ 0, >+ CTDB_CTRL_FLAG_NOREPLY, >+ tdb_null, >+ NULL, >+ NULL); >+ >+ D_NOTICE("Dropping all public IP addresses\n"); >+ ctdb_release_all_ips(ctdb); >+} > > int32_t ctdb_control_stop_node(struct ctdb_context *ctdb) > { >-- >2.17.1 > > >From a93c591a11a9b19f4f5df87c76e3b2f3f7404339 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 19 Aug 2019 21:52:57 +1000 >Subject: [PATCH 096/376] ctdb-daemon: Switch banning code to use > ctdb_node_become_inactive() > >There's no reason to avoid immediately setting recovery mode to active >and initiating freeze of databases. > >This effectively reverts the following commits: > > d8f3b490bbb691c9916eed0df5b980c1aef23c85 > b4357a79d916b1f8ade8fa78563fbef0ce670aa9 > >The latter is now implemented using a control, resulting in looser >coupling. > >See also the following commit: > > f8141e91a693912ea1107a49320e83702a80757a > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14087 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 0f5f7b7cf4e970f3f36c5e0b3d09e710fe90801a) >--- > ctdb/server/ctdb_banning.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/ctdb/server/ctdb_banning.c b/ctdb/server/ctdb_banning.c >index 9cd163645a1..11794dc5b0b 100644 >--- a/ctdb/server/ctdb_banning.c >+++ b/ctdb/server/ctdb_banning.c >@@ -129,7 +129,7 @@ int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) > ctdb_ban_node_event, ctdb); > > if (!already_banned) { >- ctdb_local_node_got_banned(ctdb); >+ ctdb_node_become_inactive(ctdb); > } > return 0; > } >-- >2.17.1 > > >From f454db8d960bce78e492cdec344257a2ee094514 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Tue, 20 Aug 2019 11:29:42 +1000 >Subject: [PATCH 097/376] ctdb-daemon: Drop unused function > ctdb_local_node_got_banned() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14087 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 91ac4c13d8472955d1f04bd775ec4b3ff8bf1b61) >--- > ctdb/include/ctdb_private.h | 1 - > ctdb/server/ctdb_banning.c | 24 ------------------------ > 2 files changed, 25 deletions(-) > >diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h >index d9d13fad358..1f168dae2b8 100644 >--- a/ctdb/include/ctdb_private.h >+++ b/ctdb/include/ctdb_private.h >@@ -481,7 +481,6 @@ int ctdb_ibw_init(struct ctdb_context *ctdb); > > /* from ctdb_banning.c */ > >-void ctdb_local_node_got_banned(struct ctdb_context *ctdb); > int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata); > int32_t ctdb_control_get_ban_state(struct ctdb_context *ctdb, TDB_DATA *outdata); > void ctdb_ban_self(struct ctdb_context *ctdb); >diff --git a/ctdb/server/ctdb_banning.c b/ctdb/server/ctdb_banning.c >index 11794dc5b0b..3c711575e8c 100644 >--- a/ctdb/server/ctdb_banning.c >+++ b/ctdb/server/ctdb_banning.c >@@ -57,30 +57,6 @@ static void ctdb_ban_node_event(struct tevent_context *ev, > } > } > >-void ctdb_local_node_got_banned(struct ctdb_context *ctdb) >-{ >- struct ctdb_db_context *ctdb_db; >- >- DEBUG(DEBUG_NOTICE, ("This node has been banned - releasing all public " >- "IPs and setting the generation to INVALID.\n")); >- >- /* Reset the generation id to 1 to make us ignore any >- REQ/REPLY CALL/DMASTER someone sends to us. >- We are now banned so we shouldnt service database calls >- anymore. >- */ >- ctdb->vnn_map->generation = INVALID_GENERATION; >- for (ctdb_db = ctdb->db_list; ctdb_db != NULL; ctdb_db = ctdb_db->next) { >- ctdb_db->generation = INVALID_GENERATION; >- } >- >- /* Recovery daemon will set the recovery mode ACTIVE and freeze >- * databases. >- */ >- >- ctdb_release_all_ips(ctdb); >-} >- > int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata) > { > struct ctdb_ban_state *bantime = (struct ctdb_ban_state *)indata.dptr; >-- >2.17.1 > > >From a9d0e0b7bae9005d56222e5952f9fec66cb8f491 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 19 Aug 2019 21:48:04 +1000 >Subject: [PATCH 098/376] ctdb-daemon: Make node inactive in the NODE_STOP > control > >Currently some of this is supported by a periodic check in the >recovery daemon's main_loop(), which notices the flag change, sets >recovery mode active and freezes databases. If STOP_NODE returns >immediately then the associated recovery can complete and the node can >be continued before databases are actually frozen. > >Instead, immediately do all of the things that make a node inactive. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14087 >RN: Stop "ctdb stop" from completing before freezing databases > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Amitay Isaacs <amitay@samba.org> >Autobuild-Date(master): Tue Aug 20 08:32:27 UTC 2019 on sn-devel-184 > >(cherry picked from commit e9f2e205ee89f4f3d6302cc11b4d0eb2efaf0f53) >--- > ctdb/server/ctdb_recover.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/ctdb/server/ctdb_recover.c b/ctdb/server/ctdb_recover.c >index df60a4cb9c0..1654c6d3978 100644 >--- a/ctdb/server/ctdb_recover.c >+++ b/ctdb/server/ctdb_recover.c >@@ -1469,6 +1469,8 @@ int32_t ctdb_control_stop_node(struct ctdb_context *ctdb) > DEBUG(DEBUG_ERR, ("Stopping node\n")); > ctdb->nodes[ctdb->pnn]->flags |= NODE_FLAGS_STOPPED; > >+ ctdb_node_become_inactive(ctdb); >+ > return 0; > } > >-- >2.17.1 > > >From d61fac0cbe4abe1f90da6aea695690ccdb757765 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Sat, 17 Aug 2019 06:59:33 +1200 >Subject: [PATCH 099/376] docs: Deprecate "rndc command" for Samba 4.11 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14092 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 561e0986ac96c842239b4e8c6509e05c836707b7) >--- > docs-xml/smbdotconf/domain/rndccommand.xml | 7 +++++++ > 1 file changed, 7 insertions(+) > >diff --git a/docs-xml/smbdotconf/domain/rndccommand.xml b/docs-xml/smbdotconf/domain/rndccommand.xml >index d9ac4ea6737..c9a1526c0cd 100644 >--- a/docs-xml/smbdotconf/domain/rndccommand.xml >+++ b/docs-xml/smbdotconf/domain/rndccommand.xml >@@ -1,10 +1,17 @@ > <samba:parameter name="rndc command" > context="G" > type="cmdlist" >+ deprecated="1" > xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> > <description> >+ <para>This option is deprecated with Samba 4.11 and will be removed >+ in future. >+ </para> > <para>This option specifies the path to the name server control utility. > </para> >+ <para>This option is only useful when Samba as an AD DC is >+ configured with BIND9_FLATFILE for DNS. >+ </para> > > <para>The <filename>rndc</filename> utility should be a part of the > bind installation. >-- >2.17.1 > > >From aa3ad5c451f38659c1131b20756ad81a903654cb Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Fri, 23 Aug 2019 21:13:22 +1200 >Subject: [PATCH 100/376] WHATSNEW: BIND9_FLATFILE / rndc command deprecated > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Aug 28 10:48:10 UTC 2019 on sn-devel-184 >--- > WHATSNEW.txt | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index 6a0cc9d72fd..c273117c72f 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -68,6 +68,20 @@ in the following years. If you have a strong requirement for SMB1 > (except for supporting old Linux Kernels), please file a bug > at https://bugzilla.samba.org and let us know about the details. > >+BIND9_FLATFILE deprecated >+------------------------- >+ >+The BIND9_FLATFILE DNS backend is deprecated in this release and will >+be removed in the future. This was only practically useful on a single >+domain controller or under expert care and supervision. >+ >+This release therefore deprecates the "rndc command" smb.conf >+parameter, which is used to support this configuration. After writing >+out a list of DCs permitted to make changes to the DNS Zone "rndc >+command" is called with reload to tell the 'named' server if a DC was >+added/removed to to the domain. >+ >+ > NEW FEATURES/CHANGES > ==================== > >@@ -342,6 +356,7 @@ smb.conf changes > web port Removed > fruit:zero_file_id Changed default False > debug encryption New: dump encryption keys False >+ rndc command Deprecated > > > KNOWN ISSUES >-- >2.17.1 > > >From bcfb7749869241a6a85fedca551ae6a4a4dec4fc Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 12 Jul 2019 12:10:35 -0700 >Subject: [PATCH 101/376] CVE-2019-10197: smbd: separate out impersonation > debug info into a new function. > >Will be called on elsewhere on successful impersonation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/uid.c | 37 +++++++++++++++++++++++-------------- > 1 file changed, 23 insertions(+), 14 deletions(-) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index a4bcb747d37..ce8e8d92131 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -279,6 +279,28 @@ static bool check_user_ok(connection_struct *conn, > return(True); > } > >+static void print_impersonation_info(connection_struct *conn) >+{ >+ struct smb_filename *cwdfname = NULL; >+ >+ if (!CHECK_DEBUGLVL(DBGLVL_INFO)) { >+ return; >+ } >+ >+ cwdfname = vfs_GetWd(talloc_tos(), conn); >+ if (cwdfname == NULL) { >+ return; >+ } >+ >+ DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n", >+ (int)getuid(), >+ (int)geteuid(), >+ (int)getgid(), >+ (int)getegid(), >+ cwdfname->base_name); >+ TALLOC_FREE(cwdfname); >+} >+ > /**************************************************************************** > Become the user of a connection number without changing the security context > stack, but modify the current_user entries. >@@ -415,20 +437,7 @@ static bool change_to_user_internal(connection_struct *conn, > current_user.done_chdir = true; > } > >- if (CHECK_DEBUGLVL(DBGLVL_INFO)) { >- struct smb_filename *cwdfname = vfs_GetWd(talloc_tos(), conn); >- if (cwdfname == NULL) { >- return false; >- } >- DBG_INFO("Impersonated user: uid=(%d,%d), gid=(%d,%d), cwd=[%s]\n", >- (int)getuid(), >- (int)geteuid(), >- (int)getgid(), >- (int)getegid(), >- cwdfname->base_name); >- TALLOC_FREE(cwdfname); >- } >- >+ print_impersonation_info(conn); > return true; > } > >-- >2.17.1 > > >From ae9bdef5c8a2dea2efca6295799a42ba01c3b98d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 11 Jul 2019 17:01:29 +0200 >Subject: [PATCH 102/376] CVE-2019-10197: smbd: make sure that > change_to_user_internal() always resets current_user.done_chdir > >We should not leave current_user.done_chdir as true if we didn't call >chdir_current_service() with success. > >This caused problems in when calling vfs_ChDir() in pop_conn_ctx() when >chdir_current_service() worked once on one share but later failed on another >share. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >--- > source3/smbd/uid.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index ce8e8d92131..77a81f60298 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -427,6 +427,7 @@ static bool change_to_user_internal(connection_struct *conn, > current_user.conn = conn; > current_user.vuid = vuid; > current_user.need_chdir = conn->tcon_done; >+ current_user.done_chdir = false; > > if (current_user.need_chdir) { > ok = chdir_current_service(conn); >-- >2.17.1 > > >From d690f6f3c4d82a5ff887df40e2a60a1828eb87eb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 18 Jun 2019 14:04:08 +0200 >Subject: [PATCH 103/376] CVE-2019-10197: smbd: make sure we reset > current_user.{need,done}_chdir in become_root() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > source3/smbd/uid.c | 3 +++ > 1 file changed, 3 insertions(+) > >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index 77a81f60298..50868ba8572 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -624,6 +624,9 @@ void smbd_become_root(void) > } > push_conn_ctx(); > set_root_sec_ctx(); >+ >+ current_user.need_chdir = false; >+ current_user.done_chdir = false; > } > > /* Unbecome the root user */ >-- >2.17.1 > > >From 7b39df0f1449024c8b9f2954a63f0b265c4269e8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 30 Jul 2019 17:16:59 +0200 >Subject: [PATCH 104/376] CVE-2019-10197: selftest: make fsrvp_share its own > independent subdirectory > >The next patch will otherwise break the fsrvp related tests. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > selftest/target/Samba3.pm | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 5c327cab543..4cc2938e8fd 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -1449,6 +1449,9 @@ sub provision($$$$$$$$$) > my $widelinks_linkdir="$shrdir/widelinks_foo"; > push(@dirs,$widelinks_linkdir); > >+ my $fsrvp_shrdir="$shrdir/fsrvp"; >+ push(@dirs,$fsrvp_shrdir); >+ > my $shadow_tstdir="$shrdir/shadow"; > push(@dirs,$shadow_tstdir); > my $shadow_mntdir="$shadow_tstdir/mount"; >@@ -2024,14 +2027,14 @@ sub provision($$$$$$$$$) > guest ok = yes > > [fsrvp_share] >- path = $shrdir >+ path = $fsrvp_shrdir > comment = fake shapshots using rsync > vfs objects = shell_snap shadow_copy2 > shell_snap:check path command = $fake_snap_pl --check > shell_snap:create command = $fake_snap_pl --create > shell_snap:delete command = $fake_snap_pl --delete > # a relative path here fails, the snapshot dir is no longer found >- shadow:snapdir = $shrdir/.snapshots >+ shadow:snapdir = $fsrvp_shrdir/.snapshots > > [shadow1] > path = $shadow_shrdir >-- >2.17.1 > > >From a6ff560aa134fb4fa5ceaba83d29aae0bc398f4d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 16 Jul 2019 15:40:38 +0200 >Subject: [PATCH 105/376] CVE-2019-10197: test_smbclient_s3.sh: add regression > test for the no permission on share root problem > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >--- > selftest/knownfail.d/CVE-2019-10197 | 1 + > selftest/target/Samba3.pm | 12 +++++++++ > source3/script/tests/test_smbclient_s3.sh | 30 +++++++++++++++++++++++ > 3 files changed, 43 insertions(+) > create mode 100644 selftest/knownfail.d/CVE-2019-10197 > >diff --git a/selftest/knownfail.d/CVE-2019-10197 b/selftest/knownfail.d/CVE-2019-10197 >new file mode 100644 >index 00000000000..f7056bbf3ad >--- /dev/null >+++ b/selftest/knownfail.d/CVE-2019-10197 >@@ -0,0 +1 @@ >+^samba3.blackbox.smbclient_s3.*.noperm.share.regression >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 4cc2938e8fd..9638bb44f08 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -1425,6 +1425,9 @@ sub provision($$$$$$$$$) > my $ro_shrdir="$shrdir/root-tmp"; > push(@dirs,$ro_shrdir); > >+ my $noperm_shrdir="$shrdir/noperm-tmp"; >+ push(@dirs,$noperm_shrdir); >+ > my $msdfs_shrdir="$shrdir/msdfsshare"; > push(@dirs,$msdfs_shrdir); > >@@ -1495,6 +1498,11 @@ sub provision($$$$$$$$$) > chmod 0755, $piddir; > > >+ ## >+ ## Create a directory without permissions to enter >+ ## >+ chmod 0000, $noperm_shrdir; >+ > ## > ## create ro and msdfs share layout > ## >@@ -1818,6 +1826,10 @@ sub provision($$$$$$$$$) > [ro-tmp] > path = $ro_shrdir > guest ok = yes >+[noperm] >+ path = $noperm_shrdir >+ wide links = yes >+ guest ok = yes > [write-list-tmp] > path = $shrdir > read only = yes >diff --git a/source3/script/tests/test_smbclient_s3.sh b/source3/script/tests/test_smbclient_s3.sh >index bf033ccd2fb..0bae1d78fac 100755 >--- a/source3/script/tests/test_smbclient_s3.sh >+++ b/source3/script/tests/test_smbclient_s3.sh >@@ -1329,6 +1329,32 @@ EOF > fi > } > >+# >+# Regression test for CVE-2019-10197 >+# we should always get ACCESS_DENIED >+# >+test_noperm_share_regression() >+{ >+ cmd='$SMBCLIENT -U$USERNAME%$PASSWORD //$SERVER/noperm -I $SERVER_IP $LOCAL_ADDARGS -c "ls;ls" 2>&1' >+ eval echo "$cmd" >+ out=`eval $cmd` >+ ret=$? >+ if [ $ret -eq 0 ] ; then >+ echo "$out" >+ echo "failed accessing no perm share should not work" >+ return 1 >+ fi >+ >+ num=`echo "$out" | grep 'NT_STATUS_ACCESS_DENIED' | wc -l` >+ if [ "$num" -ne "2" ] ; then >+ echo "$out" >+ echo "failed num[$num] - two NT_STATUS_ACCESS_DENIED lines expected" >+ return 1 >+ fi >+ >+ return 0 >+} >+ > # Test smbclient deltree command > test_deltree() > { >@@ -1857,6 +1883,10 @@ testit "follow local symlinks" \ > test_local_symlinks || \ > failed=`expr $failed + 1` > >+testit "noperm share regression" \ >+ test_noperm_share_regression || \ >+ failed=`expr $failed + 1` >+ > testit "smbclient deltree command" \ > test_deltree || \ > failed=`expr $failed + 1` >-- >2.17.1 > > >From efd6d670997eff81c94b1ece3814b1da2c3705cb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 11 Jul 2019 17:02:15 +0200 >Subject: [PATCH 106/376] CVE-2019-10197: smbd: split > change_to_user_impersonate() out of change_to_user_internal() > >This makes sure we always call chdir_current_service() even >when we still impersonated the user. Which is important >in order to run the SMB* request within the correct working directory >and only if the user has permissions to enter that directory. > >It makes sure we always update conn->lastused_count >in chdir_current_service() for each request. > >Note that vfs_ChDir() (called from chdir_current_service()) >maintains its own cache and avoids calling SMB_VFS_CHDIR() >if possible. > >It means we still avoid syscalls if we get a multiple requests >for the same session/tcon tuple. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14035 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Ralph Boehme <slow@samba.org> >--- > selftest/knownfail.d/CVE-2019-10197 | 1 - > source3/smbd/uid.c | 21 +++++++++++++++++---- > 2 files changed, 17 insertions(+), 5 deletions(-) > delete mode 100644 selftest/knownfail.d/CVE-2019-10197 > >diff --git a/selftest/knownfail.d/CVE-2019-10197 b/selftest/knownfail.d/CVE-2019-10197 >deleted file mode 100644 >index f7056bbf3ad..00000000000 >--- a/selftest/knownfail.d/CVE-2019-10197 >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.blackbox.smbclient_s3.*.noperm.share.regression >diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c >index 50868ba8572..5c39baade5c 100644 >--- a/source3/smbd/uid.c >+++ b/source3/smbd/uid.c >@@ -306,9 +306,9 @@ static void print_impersonation_info(connection_struct *conn) > stack, but modify the current_user entries. > ****************************************************************************/ > >-static bool change_to_user_internal(connection_struct *conn, >- const struct auth_session_info *session_info, >- uint64_t vuid) >+static bool change_to_user_impersonate(connection_struct *conn, >+ const struct auth_session_info *session_info, >+ uint64_t vuid) > { > int snum; > gid_t gid; >@@ -321,7 +321,6 @@ static bool change_to_user_internal(connection_struct *conn, > > if ((current_user.conn == conn) && > (current_user.vuid == vuid) && >- (current_user.need_chdir == conn->tcon_done) && > (current_user.ut.uid == session_info->unix_token->uid)) > { > DBG_INFO("Skipping user change - already user\n"); >@@ -426,6 +425,20 @@ static bool change_to_user_internal(connection_struct *conn, > > current_user.conn = conn; > current_user.vuid = vuid; >+ return true; >+} >+ >+static bool change_to_user_internal(connection_struct *conn, >+ const struct auth_session_info *session_info, >+ uint64_t vuid) >+{ >+ bool ok; >+ >+ ok = change_to_user_impersonate(conn, session_info, vuid); >+ if (!ok) { >+ return false; >+ } >+ > current_user.need_chdir = conn->tcon_done; > current_user.done_chdir = false; > >-- >2.17.1 > > >From f04985fe9b54824fb61683c67065da2fdb8f2e1a Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 3 Sep 2019 13:12:16 +0200 >Subject: [PATCH 107/376] WHATSNEW: Add release notes for Samba 4.11.0rc3. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 47 ++++++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 46 insertions(+), 1 deletion(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index c273117c72f..eece43fcd9e 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -1,7 +1,7 @@ > Release Announcements > ===================== > >-This is the second release candidate of Samba 4.11. This is *not* >+This is the third release candidate of Samba 4.11. This is *not* > intended for production environments and is designed for testing > purposes only. Please report any defects via the Samba bug reporting > system at https://bugzilla.samba.org/. >@@ -359,6 +359,51 @@ smb.conf changes > rndc command Deprecated > > >+CHANGES SINCE 4.11.0rc2 >+======================= >+ >+o Michael Adam <obnox@samba.org> >+ * BUG 13972: Different Device Id for GlusterFS FUSE mount is causing data >+ loss in CTDB cluster. >+ >+o Jeremy Allison <jra@samba.org> >+ * BUG 14035: CVE-2019-10197: Permissions check deny can allow user to escape >+ from the share. >+ >+o Andrew Bartlett <abartlet@samba.org> >+ * BUG 14059: ldb: Release ldb 2.0.6 (log database repack so users know what >+ is happening). >+ * BUG 14092: docs: Deprecate "rndc command" for Samba 4.11. >+ >+o Tim Beale <timbeale@catalyst.net.nz> >+ * BUG 14059: ldb: Free memory when repacking database. >+ >+o Ralph Boehme <slow@samba.org> >+ * BUG 14089: vfs_default: Use correct flag in vfswrap_fs_file_id. >+ * BUG 14090: vfs_glusterfs: Initialize st_ex_file_id, st_ex_itime and >+ st_ex_iflags. >+ >+o Anoop C S <anoopcs@redhat.com> >+ * BUG 14093: vfs_glusterfs: Enable profiling for file system operations. >+ >+o Aaron Haslett <aaronhaslett@catalyst.net.nz> >+ * BUG 14059: Backport sambadowngradedatabase for v4.11. >+ >+o Stefan Metzmacher <metze@samba.org> >+ * BUG 14035: CVE-2019-10197: Permissions check deny can allow user to escape >+ from the share. >+ >+o Christof Schmitt <cs@samba.org> >+ * BUG 14032: vfs_gpfs: Implement special case for denying owner access to >+ ACL. >+ >+o Martin Schwenke <martin@meltin.net> >+ * BUG 14084: Avoid marking a node as connected before it can receive packets. >+ * BUG 14086: Fix onnode test failure with ShellCheck >= 0.4.7. >+ * BUG 14087: ctdb-daemon: Stop "ctdb stop" from completing before freezing >+ databases. >+ >+ > KNOWN ISSUES > ============ > >-- >2.17.1 > > >From c1d9e02d06a158f637475ffeca7a6c3f2fb1d773 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 3 Sep 2019 13:12:53 +0200 >Subject: [PATCH 108/376] VERSION: Disable GIT_SNAPSHOT for the 4.11.0rc3 > release. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/VERSION b/VERSION >index 67ae2000ebf..a8742ca9e50 100644 >--- a/VERSION >+++ b/VERSION >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=3 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=yes >+SAMBA_VERSION_IS_GIT_SNAPSHOT=no > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From 96961348432cd1171b99ea2d8e64d4bc9d897f72 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 3 Sep 2019 13:13:47 +0200 >Subject: [PATCH 109/376] VERSION: Bump verison up to 4.11.0rc4... > >and re-enable GIT_SNAPSHOT. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index a8742ca9e50..ae98c26560f 100644 >--- a/VERSION >+++ b/VERSION >@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= > # e.g. SAMBA_VERSION_RC_RELEASE=1 # > # -> "3.0.0rc1" # > ######################################################## >-SAMBA_VERSION_RC_RELEASE=3 >+SAMBA_VERSION_RC_RELEASE=4 > > ######################################################## > # To mark SVN snapshots this should be set to 'yes' # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=3 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=no >+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From a279b8883469b524b18e61c30621fe0dd999e054 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 15:31:55 +1000 >Subject: [PATCH 110/376] ctdb-tests: Reformat node_has_status() > >Re-indent and drop non-POSIX left-parenthesis from case labels. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 52227d19735a3305ad633672c70385f443f222f0) >--- > ctdb/tests/scripts/integration.bash | 94 +++++++++++++++-------------- > 1 file changed, 48 insertions(+), 46 deletions(-) > >diff --git a/ctdb/tests/scripts/integration.bash b/ctdb/tests/scripts/integration.bash >index 30725c48e53..e2f238d93d4 100644 >--- a/ctdb/tests/scripts/integration.bash >+++ b/ctdb/tests/scripts/integration.bash >@@ -311,53 +311,55 @@ wait_until_ready () > # This function is becoming nicely overloaded. Soon it will collapse! :-) > node_has_status () > { >- local pnn="$1" >- local status="$2" >- >- local bits fpat mpat rpat >- case "$status" in >- (unhealthy) bits="?|?|?|1|*" ;; >- (healthy) bits="?|?|?|0|*" ;; >- (disconnected) bits="1|*" ;; >- (connected) bits="0|*" ;; >- (banned) bits="?|1|*" ;; >- (unbanned) bits="?|0|*" ;; >- (disabled) bits="?|?|1|*" ;; >- (enabled) bits="?|?|0|*" ;; >- (stopped) bits="?|?|?|?|1|*" ;; >- (notstopped) bits="?|?|?|?|0|*" ;; >- (frozen) fpat='^[[:space:]]+frozen[[:space:]]+1$' ;; >- (unfrozen) fpat='^[[:space:]]+frozen[[:space:]]+0$' ;; >- (recovered) rpat='^Recovery mode:RECOVERY \(1\)$' ;; >- (notlmaster) rpat="^hash:.* lmaster:${pnn}\$" ;; >+ local pnn="$1" >+ local status="$2" >+ >+ local bits fpat mpat rpat >+ case "$status" in >+ unhealthy) bits="?|?|?|1|*" ;; >+ healthy) bits="?|?|?|0|*" ;; >+ disconnected) bits="1|*" ;; >+ connected) bits="0|*" ;; >+ banned) bits="?|1|*" ;; >+ unbanned) bits="?|0|*" ;; >+ disabled) bits="?|?|1|*" ;; >+ enabled) bits="?|?|0|*" ;; >+ stopped) bits="?|?|?|?|1|*" ;; >+ notstopped) bits="?|?|?|?|0|*" ;; >+ frozen) fpat='^[[:space:]]+frozen[[:space:]]+1$' ;; >+ unfrozen) fpat='^[[:space:]]+frozen[[:space:]]+0$' ;; >+ recovered) rpat='^Recovery mode:RECOVERY \(1\)$' ;; >+ notlmaster) rpat="^hash:.* lmaster:${pnn}\$" ;; > *) >- echo "node_has_status: unknown status \"$status\"" >- return 1 >- esac >- >- if [ -n "$bits" ] ; then >- local out x line >- >- out=$($CTDB -X status 2>&1) || return 1 >- >- { >- read x >- while read line ; do >- # This needs to be done in 2 steps to avoid false matches. >- local line_bits="${line#|${pnn}|*|}" >- [ "$line_bits" = "$line" ] && continue >- [ "${line_bits#${bits}}" != "$line_bits" ] && return 0 >- done >- return 1 >- } <<<"$out" # Yay bash! >- elif [ -n "$fpat" ] ; then >- $CTDB statistics -n "$pnn" | egrep -q "$fpat" >- elif [ -n "$rpat" ] ; then >- ! $CTDB status -n "$pnn" | egrep -q "$rpat" >- else >- echo 'node_has_status: unknown mode, neither $bits nor $fpat is set' >- return 1 >- fi >+ echo "node_has_status: unknown status \"$status\"" >+ return 1 >+ esac >+ >+ if [ -n "$bits" ] ; then >+ local out x line >+ >+ out=$($CTDB -X status 2>&1) || return 1 >+ >+ { >+ read x >+ while read line ; do >+ # This needs to be done in 2 steps to >+ # avoid false matches. >+ local line_bits="${line#|${pnn}|*|}" >+ [ "$line_bits" = "$line" ] && continue >+ [ "${line_bits#${bits}}" != "$line_bits" ] && \ >+ return 0 >+ done >+ return 1 >+ } <<<"$out" # Yay bash! >+ elif [ -n "$fpat" ] ; then >+ $CTDB statistics -n "$pnn" | egrep -q "$fpat" >+ elif [ -n "$rpat" ] ; then >+ ! $CTDB status -n "$pnn" | egrep -q "$rpat" >+ else >+ echo 'node_has_status: unknown mode, neither $bits nor $fpat is set' >+ return 1 >+ fi > } > > wait_until_node_has_status () >-- >2.17.1 > > >From 6efb59affb25594828e4cc68a30ea41e71f0b124 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 15:40:16 +1000 >Subject: [PATCH 111/376] ctdb-tests: Drop unused node statuses frozen/unfrozen > >Silently drop unused local variable mpat. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 9b09a87326af28877301ad27bcec5bb13744e2b6) >--- > ctdb/tests/scripts/integration.bash | 8 ++------ > 1 file changed, 2 insertions(+), 6 deletions(-) > >diff --git a/ctdb/tests/scripts/integration.bash b/ctdb/tests/scripts/integration.bash >index e2f238d93d4..60323e33a97 100644 >--- a/ctdb/tests/scripts/integration.bash >+++ b/ctdb/tests/scripts/integration.bash >@@ -314,7 +314,7 @@ node_has_status () > local pnn="$1" > local status="$2" > >- local bits fpat mpat rpat >+ local bits rpat > case "$status" in > unhealthy) bits="?|?|?|1|*" ;; > healthy) bits="?|?|?|0|*" ;; >@@ -326,8 +326,6 @@ node_has_status () > enabled) bits="?|?|0|*" ;; > stopped) bits="?|?|?|?|1|*" ;; > notstopped) bits="?|?|?|?|0|*" ;; >- frozen) fpat='^[[:space:]]+frozen[[:space:]]+1$' ;; >- unfrozen) fpat='^[[:space:]]+frozen[[:space:]]+0$' ;; > recovered) rpat='^Recovery mode:RECOVERY \(1\)$' ;; > notlmaster) rpat="^hash:.* lmaster:${pnn}\$" ;; > *) >@@ -352,12 +350,10 @@ node_has_status () > done > return 1 > } <<<"$out" # Yay bash! >- elif [ -n "$fpat" ] ; then >- $CTDB statistics -n "$pnn" | egrep -q "$fpat" > elif [ -n "$rpat" ] ; then > ! $CTDB status -n "$pnn" | egrep -q "$rpat" > else >- echo 'node_has_status: unknown mode, neither $bits nor $fpat is set' >+ echo 'node_has_status: unknown mode, neither $bits nor $rpat is set' > return 1 > fi > } >-- >2.17.1 > > >From e876b1e85627db8be59bcbcede7154a55f640b00 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 15:45:41 +1000 >Subject: [PATCH 112/376] ctdb-tests: Inline handling of recovered and > notlmaster statuses > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit bb59073515ee5f7886b5d9a20d7b2805857c2708) >--- > ctdb/tests/scripts/integration.bash | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) > >diff --git a/ctdb/tests/scripts/integration.bash b/ctdb/tests/scripts/integration.bash >index 60323e33a97..d8411edc588 100644 >--- a/ctdb/tests/scripts/integration.bash >+++ b/ctdb/tests/scripts/integration.bash >@@ -314,7 +314,7 @@ node_has_status () > local pnn="$1" > local status="$2" > >- local bits rpat >+ local bits > case "$status" in > unhealthy) bits="?|?|?|1|*" ;; > healthy) bits="?|?|?|0|*" ;; >@@ -326,8 +326,16 @@ node_has_status () > enabled) bits="?|?|0|*" ;; > stopped) bits="?|?|?|?|1|*" ;; > notstopped) bits="?|?|?|?|0|*" ;; >- recovered) rpat='^Recovery mode:RECOVERY \(1\)$' ;; >- notlmaster) rpat="^hash:.* lmaster:${pnn}\$" ;; >+ recovered) >+ ! $CTDB status -n "$pnn" | \ >+ grep -Eq '^Recovery mode:RECOVERY \(1\)$' >+ return >+ ;; >+ notlmaster) >+ ! $CTDB status -n "$pnn" | \ >+ grep -Eq "^hash:.* lmaster:${pnn}\$" >+ return >+ ;; > *) > echo "node_has_status: unknown status \"$status\"" > return 1 >@@ -350,10 +358,8 @@ node_has_status () > done > return 1 > } <<<"$out" # Yay bash! >- elif [ -n "$rpat" ] ; then >- ! $CTDB status -n "$pnn" | egrep -q "$rpat" > else >- echo 'node_has_status: unknown mode, neither $bits nor $rpat is set' >+ echo 'node_has_status: unknown mode, $bits not set' > return 1 > fi > } >-- >2.17.1 > > >From 7e004230708001878e6b278aab32b6854289dc6a Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 16:43:09 +1000 >Subject: [PATCH 113/376] ctdb-tests: Handle special cases first and return > >All the other cases involve matching bits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit bff1a3a548a2cace997b767d78bb824438664cb7) >--- > ctdb/tests/scripts/integration.bash | 59 ++++++++++++++--------------- > 1 file changed, 28 insertions(+), 31 deletions(-) > >diff --git a/ctdb/tests/scripts/integration.bash b/ctdb/tests/scripts/integration.bash >index d8411edc588..3fb6f9ade5e 100644 >--- a/ctdb/tests/scripts/integration.bash >+++ b/ctdb/tests/scripts/integration.bash >@@ -314,6 +314,19 @@ node_has_status () > local pnn="$1" > local status="$2" > >+ case "$status" in >+ recovered) >+ ! $CTDB status -n "$pnn" | \ >+ grep -Eq '^Recovery mode:RECOVERY \(1\)$' >+ return >+ ;; >+ notlmaster) >+ ! $CTDB status -n "$pnn" | \ >+ grep -Eq "^hash:.* lmaster:${pnn}\$" >+ return >+ ;; >+ esac >+ > local bits > case "$status" in > unhealthy) bits="?|?|?|1|*" ;; >@@ -326,42 +339,26 @@ node_has_status () > enabled) bits="?|?|0|*" ;; > stopped) bits="?|?|?|?|1|*" ;; > notstopped) bits="?|?|?|?|0|*" ;; >- recovered) >- ! $CTDB status -n "$pnn" | \ >- grep -Eq '^Recovery mode:RECOVERY \(1\)$' >- return >- ;; >- notlmaster) >- ! $CTDB status -n "$pnn" | \ >- grep -Eq "^hash:.* lmaster:${pnn}\$" >- return >- ;; > *) > echo "node_has_status: unknown status \"$status\"" > return 1 > esac >- >- if [ -n "$bits" ] ; then >- local out x line >- >- out=$($CTDB -X status 2>&1) || return 1 >- >- { >- read x >- while read line ; do >- # This needs to be done in 2 steps to >- # avoid false matches. >- local line_bits="${line#|${pnn}|*|}" >- [ "$line_bits" = "$line" ] && continue >- [ "${line_bits#${bits}}" != "$line_bits" ] && \ >- return 0 >- done >- return 1 >- } <<<"$out" # Yay bash! >- else >- echo 'node_has_status: unknown mode, $bits not set' >+ local out x line >+ >+ out=$($CTDB -X status 2>&1) || return 1 >+ >+ { >+ read x >+ while read line ; do >+ # This needs to be done in 2 steps to >+ # avoid false matches. >+ local line_bits="${line#|${pnn}|*|}" >+ [ "$line_bits" = "$line" ] && continue >+ [ "${line_bits#${bits}}" != "$line_bits" ] && \ >+ return 0 >+ done > return 1 >- fi >+ } <<<"$out" # Yay bash! > } > > wait_until_node_has_status () >-- >2.17.1 > > >From 4a5c554508b14be280bddb7c16688868c980abf0 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 16:45:07 +1000 >Subject: [PATCH 114/376] ctdb-tests: Don't retrieve the VNN map from target > node for notlmaster > >Use the VNN map from the node running node_has_status(). > >This means that > > wait_until_node_has_status 1 notlmaster 10 0 > >will run "ctdb status" on node 0 and check (for up to 10 seconds) if >node 1 is in the VNN map. > >If the LMASTER capability has been dropped on node 1 then the above >will wait for the VNN map to be updated on node 0. This will happen >as part of the recovery that is triggered by the change of LMASTER >capability. The next command will then only be able to attach to >$TESTDB after the recovery is complete thus guaranteeing a sane state >for the test to continue. > >This stops simple/79_volatile_db_traverse.sh from going into recovery >during the traverse or at some other inconvenient time. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 53daeb2f878af1634a26e05cb86d87e2faf20173) >--- > ctdb/tests/scripts/integration.bash | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/ctdb/tests/scripts/integration.bash b/ctdb/tests/scripts/integration.bash >index 3fb6f9ade5e..a4d45fb9ac2 100644 >--- a/ctdb/tests/scripts/integration.bash >+++ b/ctdb/tests/scripts/integration.bash >@@ -321,8 +321,7 @@ node_has_status () > return > ;; > notlmaster) >- ! $CTDB status -n "$pnn" | \ >- grep -Eq "^hash:.* lmaster:${pnn}\$" >+ ! $CTDB status | grep -Eq "^hash:.* lmaster:${pnn}\$" > return > ;; > esac >-- >2.17.1 > > >From a03443efef6488a5b2dc74962f77070c0c8ecb06 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Wed, 21 Aug 2019 14:35:09 +1000 >Subject: [PATCH 115/376] ctdb-recoverd: Only check for LMASTER nodes in the > VNN map > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 5d655ac6f2ff82f8f1c89b06870d600a1a3c7a8a) >--- > ctdb/server/ctdb_recoverd.c | 14 ++++++++++---- > 1 file changed, 10 insertions(+), 4 deletions(-) > >diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c >index 652bf9ce4ea..a190d0c9985 100644 >--- a/ctdb/server/ctdb_recoverd.c >+++ b/ctdb/server/ctdb_recoverd.c >@@ -2989,13 +2989,19 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec, > return; > } > >- /* verify that all active nodes in the nodemap also exist in >- the vnnmap. >+ /* >+ * Verify that all active lmaster nodes in the nodemap also >+ * exist in the vnnmap > */ > for (j=0; j<nodemap->num; j++) { > if (nodemap->nodes[j].flags & NODE_FLAGS_INACTIVE) { > continue; > } >+ if (! ctdb_node_has_capabilities(rec->caps, >+ ctdb->nodes[j]->pnn, >+ CTDB_CAP_LMASTER)) { >+ continue; >+ } > if (nodemap->nodes[j].pnn == pnn) { > continue; > } >@@ -3006,8 +3012,8 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec, > } > } > if (i == vnnmap->size) { >- DEBUG(DEBUG_ERR, (__location__ " Node %u is active in the nodemap but did not exist in the vnnmap\n", >- nodemap->nodes[j].pnn)); >+ D_ERR("Active LMASTER node %u is not in the vnnmap\n", >+ nodemap->nodes[j].pnn); > ctdb_set_culprit(rec, nodemap->nodes[j].pnn); > do_recovery(rec, mem_ctx, pnn, nodemap, vnnmap); > return; >-- >2.17.1 > > >From 9063f5dde3f9fc43037539e4424944400c00ddb5 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Mon, 29 Jul 2019 17:22:50 +1000 >Subject: [PATCH 116/376] ctdb-tests: Strengthen volatile DB traverse test > >Check the record count more often, from multiple nodes. Add a case >with multiple records. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit ca4df06080709adf0cbebc95b0a70b4090dad5ba) >--- > ctdb/tests/simple/79_volatile_db_traverse.sh | 67 +++++++++++++++----- > 1 file changed, 52 insertions(+), 15 deletions(-) > >diff --git a/ctdb/tests/simple/79_volatile_db_traverse.sh b/ctdb/tests/simple/79_volatile_db_traverse.sh >index af7e962f579..7f3007d5105 100755 >--- a/ctdb/tests/simple/79_volatile_db_traverse.sh >+++ b/ctdb/tests/simple/79_volatile_db_traverse.sh >@@ -42,11 +42,56 @@ try_command_on_node 0 $CTDB writekey "$TESTDB" "foo" "bar0" > echo "write foo=bar1 on node 1" > try_command_on_node 1 $CTDB writekey "$TESTDB" "foo" "bar1" > >-echo "do traverse on node 0" >-try_command_on_node -v 0 $CTDB catdb "$TESTDB" >+echo > >-echo "do traverse on node 1" >-try_command_on_node -v 1 $CTDB catdb "$TESTDB" >+check_db_num_records () >+{ >+ local node="$1" >+ local db="$2" >+ local n="$3" >+ >+ echo "Checking on node ${node} to ensure ${db} has ${n} records..." >+ try_command_on_node "$node" "${CTDB} catdb ${db}" >+ >+ num=$(sed -n -e 's|^Dumped \(.*\) records$|\1|p' "$outfile") >+ if [ "$num" = "$n" ] ; then >+ echo "OK: Number of records=${num}" >+ echo >+ else >+ echo "BAD: There were ${num} (!= ${n}) records" >+ cat "$outfile" >+ exit 1 >+ fi >+} >+ >+check_db_num_records 0 "$TESTDB" 1 >+check_db_num_records 1 "$TESTDB" 1 >+ >+cat <<EOF >+ >+Again, this time with 10 records, rewriting 5 of them on the 2nd node >+ >+EOF >+ >+echo "wipe test database $TESTDB" >+try_command_on_node 0 $CTDB wipedb "$TESTDB" >+ >+for i in $(seq 0 9) ; do >+ k="foo${i}" >+ v="bar${i}@0" >+ echo "write ${k}=${v} on node 0" >+ try_command_on_node 0 "${CTDB} writekey ${TESTDB} ${k} ${v}" >+done >+ >+for i in $(seq 1 5) ; do >+ k="foo${i}" >+ v="bar${i}@1" >+ echo "write ${k}=${v} on node 1" >+ try_command_on_node 1 "${CTDB} writekey ${TESTDB} ${k} ${v}" >+done >+ >+check_db_num_records 0 "$TESTDB" 10 >+check_db_num_records 1 "$TESTDB" 10 > > cat <<EOF > >@@ -63,8 +108,6 @@ try_command_on_node 1 $CTDB setlmasterrole off > try_command_on_node -v 1 $CTDB getcapabilities > > wait_until_node_has_status 1 notlmaster 10 0 >-# Wait for recovery and new VNN map to be pushed >-#sleep_for 10 > > echo "write foo=bar0 on node 0" > try_command_on_node 0 $CTDB writekey "$TESTDB" "foo" "bar0" >@@ -72,16 +115,10 @@ try_command_on_node 0 $CTDB writekey "$TESTDB" "foo" "bar0" > echo "write foo=bar1 on node 1" > try_command_on_node 1 $CTDB writekey "$TESTDB" "foo" "bar1" > >-echo "do traverse on node 0" >-try_command_on_node -v 0 $CTDB catdb "$TESTDB" >+echo > >-num=$(sed -n -e 's|^Dumped \(.*\) records$|\1|p' "$outfile") >-if [ "$num" = 1 ] ; then >- echo "OK: There was 1 record" >-else >- echo "BAD: There were ${num} (!= 1) records" >- exit 1 >-fi >+check_db_num_records 0 "$TESTDB" 1 >+check_db_num_records 1 "$TESTDB" 1 > > if grep -q "^data(4) = \"bar1\"\$" "$outfile" ; then > echo "OK: Data from node 1 was returned" >-- >2.17.1 > > >From 20c4d212472e177739186e9ce675fa49a5ff0a64 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Tue, 13 Aug 2019 14:45:33 +1000 >Subject: [PATCH 117/376] ctdb-tests: Clear deleted record via recovery instead > of vacuuming > >This test has been flapping because sometimes the record is not >vacuumed within the expected time period, perhaps even because the >check for the record can interfere with vacuuming. However, instead >of waiting for vacuuming the record can be cleared by doing a >recovery. This should be much more reliable. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 >RN: Fix flapping CTDB tests > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Martin Schwenke <martins@samba.org> >Autobuild-Date(master): Wed Aug 21 13:06:57 UTC 2019 on sn-devel-184 > >(cherry picked from commit 71ad473ba805abe23bbe6c1a1290612e448e73f3) >--- > .../simple/69_recovery_resurrect_deleted.sh | 17 +++++------------ > 1 file changed, 5 insertions(+), 12 deletions(-) > >diff --git a/ctdb/tests/simple/69_recovery_resurrect_deleted.sh b/ctdb/tests/simple/69_recovery_resurrect_deleted.sh >index 8126c49b83c..f6c72c59f2a 100755 >--- a/ctdb/tests/simple/69_recovery_resurrect_deleted.sh >+++ b/ctdb/tests/simple/69_recovery_resurrect_deleted.sh >@@ -54,18 +54,11 @@ database_has_zero_records () > return 0 > } > >-echo "Get vacuum interval" >-try_command_on_node -v $second $CTDB getvar VacuumInterval >-vacuum_interval="${out#* = }" >- >-echo "Wait until vacuuming deletes the record on active nodes" >-# Why 4? Steps are: >-# 1. Original node processes delete queue, asks lmaster to fetch >-# 2. lmaster recoverd fetches >-# 3. lmaster processes delete queue >-# If vacuuming is just missed then need an extra interval >-t=$((vacuum_interval * 4)) >-wait_until "${t}/10" database_has_zero_records >+echo "Trigger a recovery" >+try_command_on_node "$second" $CTDB recover >+ >+echo "Checking that database has 0 records" >+database_has_zero_records > > echo "Continue node ${first}" > try_command_on_node $first $CTDB continue >-- >2.17.1 > > >From 8b680d309798d91e4658a358831e957aaffa480b Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Tue, 27 Aug 2019 12:13:51 +1000 >Subject: [PATCH 118/376] ctdb-recoverd: Fix typo in previous fix > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14085 > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Amitay Isaacs <amitay@samba.org> >Autobuild-Date(master): Tue Aug 27 15:29:11 UTC 2019 on sn-devel-184 > >(cherry picked from commit 8190993d99284162bd8699780248bb2edfec2673) >--- > ctdb/server/ctdb_recoverd.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c >index a190d0c9985..3d5b727715a 100644 >--- a/ctdb/server/ctdb_recoverd.c >+++ b/ctdb/server/ctdb_recoverd.c >@@ -2998,7 +2998,7 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec, > continue; > } > if (! ctdb_node_has_capabilities(rec->caps, >- ctdb->nodes[j]->pnn, >+ nodemap->nodes[j].pnn, > CTDB_CAP_LMASTER)) { > continue; > } >-- >2.17.1 > > >From 0e96b2cb506f278562fe21b0b8d47da276b939c6 Mon Sep 17 00:00:00 2001 >From: Poornima G <pgurusid@redhat.com> >Date: Wed, 24 Jul 2019 15:15:33 +0530 >Subject: [PATCH 119/376] vfs_glusterfs: Use pthreadpool for scheduling aio > operations > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14098 > >Signed-off-by: Poornima G <pgurusid@redhat.com> >Reviewed-by: Guenther Deschner <gd@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Fri Aug 23 18:40:08 UTC 2019 on sn-devel-184 > >(cherry picked from commit d8863dd8cb74bb0534457ca930a71e77c367d994) >--- > source3/modules/vfs_glusterfs.c | 562 +++++++++++++++++--------------- > 1 file changed, 294 insertions(+), 268 deletions(-) > >diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c >index 483d28397f8..afb34b4b47c 100644 >--- a/source3/modules/vfs_glusterfs.c >+++ b/source3/modules/vfs_glusterfs.c >@@ -45,14 +45,11 @@ > #include "lib/util/sys_rw.h" > #include "smbprofile.h" > #include "modules/posixacl_xattr.h" >+#include "lib/pthreadpool/pthreadpool_tevent.h" > > #define DEFAULT_VOLFILE_SERVER "localhost" > #define GLUSTER_NAME_MAX 255 > >-static int read_fd = -1; >-static int write_fd = -1; >-static struct tevent_fd *aio_read_event = NULL; >- > /** > * Helper to convert struct stat to struct stat_ex. > */ >@@ -713,326 +710,283 @@ static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, > return ret; > } > >-struct glusterfs_aio_state; >- >-struct glusterfs_aio_wrapper { >- struct glusterfs_aio_state *state; >-}; >- >-struct glusterfs_aio_state { >+struct vfs_gluster_pread_state { > ssize_t ret; >- struct tevent_req *req; >- bool cancelled; >+ glfs_fd_t *fd; >+ void *buf; >+ size_t count; >+ off_t offset; >+ > struct vfs_aio_state vfs_aio_state; >- struct timespec start; > SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes); > }; > >-static int aio_wrapper_destructor(struct glusterfs_aio_wrapper *wrap) >-{ >- if (wrap->state != NULL) { >- wrap->state->cancelled = true; >- } >- >- return 0; >-} >+static void vfs_gluster_pread_do(void *private_data); >+static void vfs_gluster_pread_done(struct tevent_req *subreq); >+static int vfs_gluster_pread_state_destructor(struct vfs_gluster_pread_state *state); > >-/* >- * This function is the callback that will be called on glusterfs >- * threads once the async IO submitted is complete. To notify >- * Samba of the completion we use a pipe based queue. >- */ >-#ifdef HAVE_GFAPI_VER_7_6 >-static void aio_glusterfs_done(glfs_fd_t *fd, ssize_t ret, >- struct glfs_stat *prestat, >- struct glfs_stat *poststat, >- void *data) >-#else >-static void aio_glusterfs_done(glfs_fd_t *fd, ssize_t ret, void *data) >-#endif >+static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct >+ *handle, TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ files_struct *fsp, >+ void *data, size_t n, >+ off_t offset) > { >- struct glusterfs_aio_state *state = NULL; >- int sts = 0; >- struct timespec end; >- >- state = (struct glusterfs_aio_state *)data; >+ struct vfs_gluster_pread_state *state; >+ struct tevent_req *req, *subreq; > >- PROFILE_TIMESTAMP(&end); >+ glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ if (glfd == NULL) { >+ DBG_ERR("Failed to fetch gluster fd\n"); >+ return NULL; >+ } > >- if (ret < 0) { >- state->ret = -1; >- state->vfs_aio_state.error = errno; >- } else { >- state->ret = ret; >+ req = tevent_req_create(mem_ctx, &state, struct vfs_gluster_pread_state); >+ if (req == NULL) { >+ return NULL; > } >- state->vfs_aio_state.duration = nsec_time_diff(&end, &state->start); > >- SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); >+ state->ret = -1; >+ state->fd = glfd; >+ state->buf = data; >+ state->count = n; >+ state->offset = offset; > >- /* >- * Write the state pointer to glusterfs_aio_state to the >- * pipe, so we can call tevent_req_done() from the main thread, >- * because tevent_req_done() is not designed to be executed in >- * the multithread environment, so tevent_req_done() must be >- * executed from the smbd main thread. >- * >- * write(2) on pipes with sizes under _POSIX_PIPE_BUF >- * in size is atomic, without this, the use op pipes in this >- * code would not work. >- * >- * sys_write is a thin enough wrapper around write(2) >- * that we can trust it here. >- */ >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread, profile_p, >+ state->profile_bytes, n); >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); > >- sts = sys_write(write_fd, &state, sizeof(struct glusterfs_aio_state *)); >- if (sts < 0) { >- DEBUG(0,("\nWrite to pipe failed (%s)", strerror(errno))); >+ subreq = pthreadpool_tevent_job_send( >+ state, ev, handle->conn->sconn->pool, >+ vfs_gluster_pread_do, state); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); > } >+ tevent_req_set_callback(subreq, vfs_gluster_pread_done, req); >+ >+ talloc_set_destructor(state, vfs_gluster_pread_state_destructor); > >- return; >+ return req; > } > >-/* >- * Read each req off the pipe and process it. >- */ >-static void aio_tevent_fd_done(struct tevent_context *event_ctx, >- struct tevent_fd *fde, >- uint16_t flags, void *data) >+static void vfs_gluster_pread_do(void *private_data) > { >- struct tevent_req *req = NULL; >- struct glusterfs_aio_state *state = NULL; >- int sts = 0; >+ struct vfs_gluster_pread_state *state = talloc_get_type_abort( >+ private_data, struct vfs_gluster_pread_state); >+ struct timespec start_time; >+ struct timespec end_time; > >- /* >- * read(2) on pipes is atomic if the needed data is available >- * in the pipe, per SUS and POSIX. Because we always write >- * to the pipe in sizeof(struct tevent_req *) chunks, we can >- * always read in those chunks, atomically. >- * >- * sys_read is a thin enough wrapper around read(2) that we >- * can trust it here. >- */ >+ SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes); > >- sts = sys_read(read_fd, &state, sizeof(struct glusterfs_aio_state *)); >+ PROFILE_TIMESTAMP(&start_time); > >- if (sts < 0) { >- DEBUG(0,("\nRead from pipe failed (%s)", strerror(errno))); >- } >+ do { >+#ifdef HAVE_GFAPI_VER_7_6 >+ state->ret = glfs_pread(state->fd, state->buf, state->count, >+ state->offset, 0, NULL); >+#else >+ state->ret = glfs_pread(state->fd, state->buf, state->count, >+ state->offset, 0); >+#endif >+ } while ((state->ret == -1) && (errno == EINTR)); > >- /* if we've cancelled the op, there is no req, so just clean up. */ >- if (state->cancelled == true) { >- TALLOC_FREE(state); >- return; >+ if (state->ret == -1) { >+ state->vfs_aio_state.error = errno; > } > >- req = state->req; >+ PROFILE_TIMESTAMP(&end_time); > >- if (req) { >- tevent_req_done(req); >- } >- return; >+ state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time); >+ >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); > } > >-static bool init_gluster_aio(struct vfs_handle_struct *handle) >+static int vfs_gluster_pread_state_destructor(struct vfs_gluster_pread_state *state) > { >- int fds[2]; >- int ret = -1; >+ return -1; >+} > >- if (read_fd != -1) { >+static void vfs_gluster_pread_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_pread_state *state = tevent_req_data( >+ req, struct vfs_gluster_pread_state); >+ int ret; >+ >+ ret = pthreadpool_tevent_job_recv(subreq); >+ TALLOC_FREE(subreq); >+ SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); >+ talloc_set_destructor(state, NULL); >+ if (ret != 0) { >+ if (ret != EAGAIN) { >+ tevent_req_error(req, ret); >+ return; >+ } > /* >- * Already initialized. >+ * If we get EAGAIN from pthreadpool_tevent_job_recv() this >+ * means the lower level pthreadpool failed to create a new >+ * thread. Fallback to sync processing in that case to allow >+ * some progress for the client. > */ >- return true; >- } >- >- ret = pipe(fds); >- if (ret == -1) { >- goto fail; >- } >- >- read_fd = fds[0]; >- write_fd = fds[1]; >- >- aio_read_event = tevent_add_fd(handle->conn->sconn->ev_ctx, >- NULL, >- read_fd, >- TEVENT_FD_READ, >- aio_tevent_fd_done, >- NULL); >- if (aio_read_event == NULL) { >- goto fail; >+ vfs_gluster_pread_do(state); > } > >- return true; >-fail: >- TALLOC_FREE(aio_read_event); >- if (read_fd != -1) { >- close(read_fd); >- close(write_fd); >- read_fd = -1; >- write_fd = -1; >- } >- return false; >+ tevent_req_done(req); > } > >-static struct glusterfs_aio_state *aio_state_create(TALLOC_CTX *mem_ctx) >+static ssize_t vfs_gluster_pread_recv(struct tevent_req *req, >+ struct vfs_aio_state *vfs_aio_state) > { >- struct tevent_req *req = NULL; >- struct glusterfs_aio_state *state = NULL; >- struct glusterfs_aio_wrapper *wrapper = NULL; >+ struct vfs_gluster_pread_state *state = tevent_req_data( >+ req, struct vfs_gluster_pread_state); > >- req = tevent_req_create(mem_ctx, &wrapper, struct glusterfs_aio_wrapper); >- >- if (req == NULL) { >- return NULL; >+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { >+ return -1; > } > >- state = talloc_zero(NULL, struct glusterfs_aio_state); >- >- if (state == NULL) { >- TALLOC_FREE(req); >- return NULL; >- } >+ *vfs_aio_state = state->vfs_aio_state; >+ return state->ret; >+} > >- talloc_set_destructor(wrapper, aio_wrapper_destructor); >- state->cancelled = false; >- state->req = req; >+struct vfs_gluster_pwrite_state { >+ ssize_t ret; >+ glfs_fd_t *fd; >+ const void *buf; >+ size_t count; >+ off_t offset; > >- wrapper->state = state; >+ struct vfs_aio_state vfs_aio_state; >+ SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes); >+}; > >- return state; >-} >+static void vfs_gluster_pwrite_do(void *private_data); >+static void vfs_gluster_pwrite_done(struct tevent_req *subreq); >+static int vfs_gluster_pwrite_state_destructor(struct vfs_gluster_pwrite_state *state); > >-static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct >+static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct > *handle, TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > files_struct *fsp, >- void *data, size_t n, >+ const void *data, size_t n, > off_t offset) > { >- struct glusterfs_aio_state *state = NULL; >- struct tevent_req *req = NULL; >- int ret = 0; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ struct tevent_req *req, *subreq; >+ struct vfs_gluster_pwrite_state *state; > >+ glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { > DBG_ERR("Failed to fetch gluster fd\n"); > return NULL; > } > >- state = aio_state_create(mem_ctx); >- >- if (state == NULL) { >+ req = tevent_req_create(mem_ctx, &state, struct vfs_gluster_pwrite_state); >+ if (req == NULL) { > return NULL; > } > >- req = state->req; >+ state->ret = -1; >+ state->fd = glfd; >+ state->buf = data; >+ state->count = n; >+ state->offset = offset; > >- if (!init_gluster_aio(handle)) { >- tevent_req_error(req, EIO); >- return tevent_req_post(req, ev); >- } >- >- /* >- * aio_glusterfs_done and aio_tevent_fd_done() >- * use the raw tevent context. We need to use >- * tevent_req_defer_callback() in order to >- * use the event context we're started with. >- */ >- tevent_req_defer_callback(req, ev); >- >- SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread, profile_p, >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p, > state->profile_bytes, n); >- PROFILE_TIMESTAMP(&state->start); >- ret = glfs_pread_async(glfd, data, n, offset, 0, aio_glusterfs_done, >- state); >- if (ret < 0) { >- tevent_req_error(req, -ret); >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); >+ >+ subreq = pthreadpool_tevent_job_send( >+ state, ev, handle->conn->sconn->pool, >+ vfs_gluster_pwrite_do, state); >+ if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >+ tevent_req_set_callback(subreq, vfs_gluster_pwrite_done, req); >+ >+ talloc_set_destructor(state, vfs_gluster_pwrite_state_destructor); > > return req; > } > >-static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct >- *handle, TALLOC_CTX *mem_ctx, >- struct tevent_context *ev, >- files_struct *fsp, >- const void *data, size_t n, >- off_t offset) >+static void vfs_gluster_pwrite_do(void *private_data) > { >- struct glusterfs_aio_state *state = NULL; >- struct tevent_req *req = NULL; >- int ret = 0; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >- >- if (glfd == NULL) { >- DBG_ERR("Failed to fetch gluster fd\n"); >- return NULL; >- } >+ struct vfs_gluster_pwrite_state *state = talloc_get_type_abort( >+ private_data, struct vfs_gluster_pwrite_state); >+ struct timespec start_time; >+ struct timespec end_time; > >- state = aio_state_create(mem_ctx); >+ SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes); > >- if (state == NULL) { >- return NULL; >- } >+ PROFILE_TIMESTAMP(&start_time); > >- req = state->req; >+ do { >+#ifdef HAVE_GFAPI_VER_7_6 >+ state->ret = glfs_pwrite(state->fd, state->buf, state->count, >+ state->offset, 0, NULL, NULL); >+#else >+ state->ret = glfs_pwrite(state->fd, state->buf, state->count, >+ state->offset, 0); >+#endif >+ } while ((state->ret == -1) && (errno == EINTR)); > >- if (!init_gluster_aio(handle)) { >- tevent_req_error(req, EIO); >- return tevent_req_post(req, ev); >+ if (state->ret == -1) { >+ state->vfs_aio_state.error = errno; > } > >- /* >- * aio_glusterfs_done and aio_tevent_fd_done() >- * use the raw tevent context. We need to use >- * tevent_req_defer_callback() in order to >- * use the event context we're started with. >- */ >- tevent_req_defer_callback(req, ev); >+ PROFILE_TIMESTAMP(&end_time); > >- SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p, >- state->profile_bytes, n); >- PROFILE_TIMESTAMP(&state->start); >- ret = glfs_pwrite_async(glfd, data, n, offset, 0, aio_glusterfs_done, >- state); >- if (ret < 0) { >- tevent_req_error(req, -ret); >- return tevent_req_post(req, ev); >- } >+ state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time); > >- return req; >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); > } > >-static ssize_t vfs_gluster_recv(struct tevent_req *req, >- struct vfs_aio_state *vfs_aio_state) >+static int vfs_gluster_pwrite_state_destructor(struct vfs_gluster_pwrite_state *state) > { >- struct glusterfs_aio_wrapper *wrapper = NULL; >- int ret = 0; >+ return -1; >+} > >- wrapper = tevent_req_data(req, struct glusterfs_aio_wrapper); >+static void vfs_gluster_pwrite_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_pwrite_state *state = tevent_req_data( >+ req, struct vfs_gluster_pwrite_state); >+ int ret; > >- if (wrapper == NULL) { >- return -1; >+ ret = pthreadpool_tevent_job_recv(subreq); >+ TALLOC_FREE(subreq); >+ SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); >+ talloc_set_destructor(state, NULL); >+ if (ret != 0) { >+ if (ret != EAGAIN) { >+ tevent_req_error(req, ret); >+ return; >+ } >+ /* >+ * If we get EAGAIN from pthreadpool_tevent_job_recv() this >+ * means the lower level pthreadpool failed to create a new >+ * thread. Fallback to sync processing in that case to allow >+ * some progress for the client. >+ */ >+ vfs_gluster_pwrite_do(state); > } > >- if (wrapper->state == NULL) { >- return -1; >- } >+ tevent_req_done(req); >+} >+ >+static ssize_t vfs_gluster_pwrite_recv(struct tevent_req *req, >+ struct vfs_aio_state *vfs_aio_state) >+{ >+ struct vfs_gluster_pwrite_state *state = tevent_req_data( >+ req, struct vfs_gluster_pwrite_state); > > if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { > return -1; > } > >- *vfs_aio_state = wrapper->state->vfs_aio_state; >- ret = wrapper->state->ret; >+ *vfs_aio_state = state->vfs_aio_state; > >- /* Clean up the state, it is in a NULL context. */ >- >- TALLOC_FREE(wrapper->state); >- >- return ret; >+ return state->ret; > } > > static ssize_t vfs_gluster_pwrite(struct vfs_handle_struct *handle, >@@ -1113,60 +1067,132 @@ static int vfs_gluster_rename(struct vfs_handle_struct *handle, > return ret; > } > >+struct vfs_gluster_fsync_state { >+ ssize_t ret; >+ glfs_fd_t *fd; >+ >+ struct vfs_aio_state vfs_aio_state; >+ SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes); >+}; >+ >+static void vfs_gluster_fsync_do(void *private_data); >+static void vfs_gluster_fsync_done(struct tevent_req *subreq); >+static int vfs_gluster_fsync_state_destructor(struct vfs_gluster_fsync_state *state); >+ > static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct > *handle, TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > files_struct *fsp) > { >- struct tevent_req *req = NULL; >- struct glusterfs_aio_state *state = NULL; >- int ret = 0; >- glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); >+ struct tevent_req *req, *subreq; >+ struct vfs_gluster_fsync_state *state; > >+ glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); > if (glfd == NULL) { > DBG_ERR("Failed to fetch gluster fd\n"); > return NULL; > } > >- state = aio_state_create(mem_ctx); >- >- if (state == NULL) { >+ req = tevent_req_create(mem_ctx, &state, struct vfs_gluster_fsync_state); >+ if (req == NULL) { > return NULL; > } > >- req = state->req; >+ state->ret = -1; >+ state->fd = glfd; > >- if (!init_gluster_aio(handle)) { >- tevent_req_error(req, EIO); >+ SMBPROFILE_BYTES_ASYNC_START(syscall_asys_fsync, profile_p, >+ state->profile_bytes, 0); >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); >+ >+ subreq = pthreadpool_tevent_job_send( >+ state, ev, handle->conn->sconn->pool, vfs_gluster_fsync_do, state); >+ if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >+ tevent_req_set_callback(subreq, vfs_gluster_fsync_done, req); > >- /* >- * aio_glusterfs_done and aio_tevent_fd_done() >- * use the raw tevent context. We need to use >- * tevent_req_defer_callback() in order to >- * use the event context we're started with. >- */ >- tevent_req_defer_callback(req, ev); >+ talloc_set_destructor(state, vfs_gluster_fsync_state_destructor); > >- SMBPROFILE_BYTES_ASYNC_START(syscall_asys_fsync, profile_p, >- state->profile_bytes, 0); >- PROFILE_TIMESTAMP(&state->start); >- ret = glfs_fsync_async(glfd, aio_glusterfs_done, state); >- if (ret < 0) { >- tevent_req_error(req, -ret); >- return tevent_req_post(req, ev); >- } > return req; > } > >+static void vfs_gluster_fsync_do(void *private_data) >+{ >+ struct vfs_gluster_fsync_state *state = talloc_get_type_abort( >+ private_data, struct vfs_gluster_fsync_state); >+ struct timespec start_time; >+ struct timespec end_time; >+ >+ SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes); >+ >+ PROFILE_TIMESTAMP(&start_time); >+ >+ do { >+#ifdef HAVE_GFAPI_VER_7_6 >+ state->ret = glfs_fsync(state->fd, NULL, NULL); >+#else >+ state->ret = glfs_fsync(state->fd); >+#endif >+ } while ((state->ret == -1) && (errno == EINTR)); >+ >+ if (state->ret == -1) { >+ state->vfs_aio_state.error = errno; >+ } >+ >+ PROFILE_TIMESTAMP(&end_time); >+ >+ state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time); >+ >+ SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes); >+} >+ >+static int vfs_gluster_fsync_state_destructor(struct vfs_gluster_fsync_state *state) >+{ >+ return -1; >+} >+ >+static void vfs_gluster_fsync_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct vfs_gluster_fsync_state *state = tevent_req_data( >+ req, struct vfs_gluster_fsync_state); >+ int ret; >+ >+ ret = pthreadpool_tevent_job_recv(subreq); >+ TALLOC_FREE(subreq); >+ SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes); >+ talloc_set_destructor(state, NULL); >+ if (ret != 0) { >+ if (ret != EAGAIN) { >+ tevent_req_error(req, ret); >+ return; >+ } >+ /* >+ * If we get EAGAIN from pthreadpool_tevent_job_recv() this >+ * means the lower level pthreadpool failed to create a new >+ * thread. Fallback to sync processing in that case to allow >+ * some progress for the client. >+ */ >+ vfs_gluster_fsync_do(state); >+ } >+ >+ tevent_req_done(req); >+} >+ > static int vfs_gluster_fsync_recv(struct tevent_req *req, > struct vfs_aio_state *vfs_aio_state) > { >- /* >- * Use implicit conversion ssize_t->int >- */ >- return vfs_gluster_recv(req, vfs_aio_state); >+ struct vfs_gluster_fsync_state *state = tevent_req_data( >+ req, struct vfs_gluster_fsync_state); >+ >+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) { >+ return -1; >+ } >+ >+ *vfs_aio_state = state->vfs_aio_state; >+ return state->ret; > } > > static int vfs_gluster_stat(struct vfs_handle_struct *handle, >@@ -1862,10 +1888,10 @@ static struct vfs_fn_pointers glusterfs_fns = { > .close_fn = vfs_gluster_close, > .pread_fn = vfs_gluster_pread, > .pread_send_fn = vfs_gluster_pread_send, >- .pread_recv_fn = vfs_gluster_recv, >+ .pread_recv_fn = vfs_gluster_pread_recv, > .pwrite_fn = vfs_gluster_pwrite, > .pwrite_send_fn = vfs_gluster_pwrite_send, >- .pwrite_recv_fn = vfs_gluster_recv, >+ .pwrite_recv_fn = vfs_gluster_pwrite_recv, > .lseek_fn = vfs_gluster_lseek, > .sendfile_fn = vfs_gluster_sendfile, > .recvfile_fn = vfs_gluster_recvfile, >-- >2.17.1 > > >From 0358b3f9bc1e557a639ec63670d8c29c135e54f5 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Sat, 6 Jul 2019 23:24:43 +1200 >Subject: [PATCH 120/376] ldb: do not allow adding a DN as a base to itself > >If you try to add a dn to itself, it expands as it goes. The resulting >loop cannot end well. > >It looks like this in Python: > > dn = ldb.Dn(ldb.Ldb(), 'CN=y,DC=x') > dn.add_base(dn) > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 19a13cbe0681b3996c33f7449f69b0fb0dc5d640) >--- > lib/ldb/common/ldb_dn.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index 2e98f391467..eccb4a0ce4b 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -1357,6 +1357,10 @@ bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base) > return false; > } > >+ if (dn == base) { >+ return false; /* or we will visit infinity */ >+ } >+ > if (dn->components) { > unsigned int i; > >-- >2.17.1 > > >From 7cf6afba65641f48a5e2c326464fd97fd9f4173c Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 8 Mar 2019 12:12:00 +1300 >Subject: [PATCH 121/376] ldb_dn: free dn components on explode failure > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Noel Power <npower@samba.org> >(cherry picked from commit b136f153b83d80a91ec9d5350fdf08412d881964) >--- > lib/ldb/common/ldb_dn.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index eccb4a0ce4b..23a817edf65 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -340,7 +340,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > /* Components data space is allocated here once */ > data = talloc_array(dn->components, char, strlen(parse_dn) + 1); > if (!data) { >- return false; >+ goto failed; > } > > p = parse_dn; >-- >2.17.1 > > >From 57f00784ffac527a0f9b830339bba24784f2e294 Mon Sep 17 00:00:00 2001 >From: Swen Schillig <swen@linux.ibm.com> >Date: Wed, 31 Jul 2019 10:27:37 +0200 >Subject: [PATCH 122/376] ldb: Fix mem-leak if talloc_realloc fails >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >In case of a failing talloc_realloc(), the only reference >to the originally allocated memory is overwritten. >Instead use a temp var until success is verified. > >Signed-off-by: Swen Schillig <swen@linux.ibm.com> >Reviewed-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 99b4791cfe423b19f1f21d5f9fb42157336019f1) >--- > lib/ldb/common/ldb_dn.c | 15 ++++++++++----- > 1 file changed, 10 insertions(+), 5 deletions(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index 23a817edf65..9b2fa966e11 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -376,6 +376,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > } > > if (in_ex_value && *p == '>') { >+ struct ldb_dn_ext_component *ext_comp = NULL; > const struct ldb_dn_extended_syntax *ext_syntax; > struct ldb_val ex_val = { > .data = (uint8_t *)ex_value, >@@ -388,15 +389,19 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > > /* Process name and ex_value */ > >- dn->ext_components = talloc_realloc(dn, >- dn->ext_components, >- struct ldb_dn_ext_component, >- dn->ext_comp_num + 1); >- if ( ! dn->ext_components) { >+ ext_comp = talloc_realloc( >+ dn, >+ dn->ext_components, >+ struct ldb_dn_ext_component, >+ dn->ext_comp_num + 1); >+ >+ if (ext_comp == NULL) { > /* ouch ! */ > goto failed; > } > >+ dn->ext_components = ext_comp; >+ > ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); > if (!ext_syntax) { > /* We don't know about this type of extended DN */ >-- >2.17.1 > > >From 9c677a274d49026105c72c5b4767b1d88eff77fa Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 26 Aug 2019 13:04:07 +1200 >Subject: [PATCH 123/376] ldb: Correct Pigeonhole principle validation in > ldb_filter_attrs() > >Thankfully this only fails if the DB is corrupt and has a duplicate record. > >The test was at the wrong end of the loop, and was for the >wrong boundary condition. A write after the end of the array would >occour before the condition was hit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13695 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit b1eec5b196e3d5a5716a5c74cf669ceaa5c0301f) >--- > lib/ldb/common/ldb_pack.c | 31 +- > lib/ldb/tests/ldb_filter_attrs_test.c | 986 ++++++++++++++++++++++++++ > lib/ldb/wscript | 5 + > 3 files changed, 1013 insertions(+), 9 deletions(-) > create mode 100644 lib/ldb/tests/ldb_filter_attrs_test.c > >diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c >index 9d87a10b9f1..1d67622b69e 100644 >--- a/lib/ldb/common/ldb_pack.c >+++ b/lib/ldb/common/ldb_pack.c >@@ -1163,7 +1163,10 @@ int ldb_filter_attrs(struct ldb_context *ldb, > } else if (i == 0) { > return 0; > >- /* Otherwise we are copying at most as many element as we have attributes */ >+ /* >+ * Otherwise we are copying at most as many elements as we >+ * have attributes >+ */ > } else { > elements_size = i; > } >@@ -1177,7 +1180,12 @@ int ldb_filter_attrs(struct ldb_context *ldb, > > for (i = 0; i < msg->num_elements; i++) { > struct ldb_message_element *el = &msg->elements[i]; >- struct ldb_message_element *el2 = &filtered_msg->elements[num_elements]; >+ >+ /* >+ * el2 is assigned after the Pigeonhole principle >+ * check below for clarity >+ */ >+ struct ldb_message_element *el2 = NULL; > unsigned int j; > > if (keep_all == false) { >@@ -1193,6 +1201,18 @@ int ldb_filter_attrs(struct ldb_context *ldb, > continue; > } > } >+ >+ /* >+ * Pigeonhole principle: we can't have more elements >+ * than the number of attributes if they are unique in >+ * the DB. >+ */ >+ if (num_elements >= elements_size) { >+ goto failed; >+ } >+ >+ el2 = &filtered_msg->elements[num_elements]; >+ > *el2 = *el; > el2->name = talloc_strdup(filtered_msg->elements, > el->name); >@@ -1211,13 +1231,6 @@ int ldb_filter_attrs(struct ldb_context *ldb, > } > } > num_elements++; >- >- /* Pidginhole principle: we can't have more elements >- * than the number of attributes if they are unique in >- * the DB */ >- if (num_elements > elements_size) { >- goto failed; >- } > } > > filtered_msg->num_elements = num_elements; >diff --git a/lib/ldb/tests/ldb_filter_attrs_test.c b/lib/ldb/tests/ldb_filter_attrs_test.c >new file mode 100644 >index 00000000000..d04775879ac >--- /dev/null >+++ b/lib/ldb/tests/ldb_filter_attrs_test.c >@@ -0,0 +1,986 @@ >+/* >+ * Tests exercising the ldb_filter_attrs(). >+ * >+ * >+ * Copyright (C) Catalyst.NET Ltd 2017 >+ * Copyright (C) Andrew Bartlett <abartlet@samba.org> 2019 >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 3 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program. If not, see <http://www.gnu.org/licenses/>. >+ * >+ */ >+ >+/* >+ * from cmocka.c: >+ * These headers or their equivalents should be included prior to >+ * including >+ * this header file. >+ * >+ * #include <stdarg.h> >+ * #include <stddef.h> >+ * #include <setjmp.h> >+ * >+ * This allows test applications to use custom definitions of C standard >+ * library functions and types. >+ */ >+#include <stdarg.h> >+#include <stddef.h> >+#include <stdint.h> >+#include <setjmp.h> >+#include <cmocka.h> >+ >+#include "../include/ldb.h" >+#include "../include/ldb_module.h" >+ >+struct ldbtest_ctx { >+ struct tevent_context *ev; >+ struct ldb_context *ldb; >+}; >+ >+/* >+ * NOTE WELL: >+ * >+ * This test checks the current behaviour of the function, however >+ * this is not in a public ABI and many of the tested behaviours are >+ * not ideal. If the behaviour is deliberatly improved, this test >+ * should be updated without worry to the new better behaviour. >+ * >+ * In particular the test is particularly to ensure the current >+ * behaviour is memory-safe. >+ */ >+ >+static int setup(void **state) >+{ >+ struct ldbtest_ctx *test_ctx; >+ >+ test_ctx = talloc_zero(NULL, struct ldbtest_ctx); >+ assert_non_null(test_ctx); >+ >+ test_ctx->ev = tevent_context_init(test_ctx); >+ assert_non_null(test_ctx->ev); >+ >+ test_ctx->ldb = ldb_init(test_ctx, test_ctx->ev); >+ assert_non_null(test_ctx->ldb); >+ >+ *state = test_ctx; >+ return 0; >+} >+ >+static int teardown(void **state) >+{ >+ talloc_free(*state); >+ return 0; >+} >+ >+ >+/* >+ * Test against a record with only one attribute, matching the one in >+ * the list >+ */ >+static void test_filter_attrs_one_attr_matched(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"foo", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ >+ /* >+ * assert the ldb_filter_attrs does not read or modify >+ * filtered_msg.dn in this case >+ */ >+ assert_null(filtered_msg->dn); >+ assert_int_equal(filtered_msg->num_elements, 1); >+ assert_string_equal(filtered_msg->elements[0].name, "foo"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value, sizeof(value)); >+} >+ >+/* >+ * Test against a record with only one attribute, matching the one of >+ * the multiple attributes in the list >+ */ >+static void test_filter_attrs_one_attr_matched_of_many(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"foo", "bar", "baz", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ >+ /* >+ * assert the ldb_filter_attrs does not read or modify >+ * filtered_msg.dn in this case >+ */ >+ assert_null(filtered_msg->dn); >+ assert_int_equal(filtered_msg->num_elements, 1); >+ assert_string_equal(filtered_msg->elements[0].name, "foo"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value, sizeof(value)); >+} >+ >+/* >+ * Test against a record with only one attribute, matching both >+ * attributes in the list >+ */ >+static void test_filter_attrs_two_attr_matched_attrs(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ /* deliberatly the other order */ >+ const char *attrs[] = {"bar", "foo", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 2); >+ >+ /* >+ * assert the ldb_filter_attrs does not read or modify >+ * filtered_msg.dn in this case >+ */ >+ assert_null(filtered_msg->dn); >+ >+ /* Assert that DB order is preserved */ >+ assert_string_equal(filtered_msg->elements[0].name, "foo"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value1)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value1, sizeof(value1)); >+ assert_string_equal(filtered_msg->elements[1].name, "bar"); >+ assert_int_equal(filtered_msg->elements[1].num_values, 1); >+ assert_int_equal(filtered_msg->elements[1].values[0].length, >+ sizeof(value2)); >+ assert_memory_equal(filtered_msg->elements[1].values[0].data, >+ value2, sizeof(value2)); >+} >+ >+/* >+ * Test against a record with two attributes, only of which is in >+ * the list >+ */ >+static void test_filter_attrs_two_attr_matched_one_attr(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ /* deliberatly the other order */ >+ const char *attrs[] = {"bar", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 1); >+ >+ /* >+ * assert the ldb_filter_attrs does not read or modify >+ * filtered_msg.dn in this case >+ */ >+ assert_null(filtered_msg->dn); >+ >+ /* Assert that DB order is preserved */ >+ assert_string_equal(filtered_msg->elements[0].name, "bar"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value2)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value2, sizeof(value2)); >+} >+ >+/* >+ * Test against a record with two attributes, both matching the one >+ * specified attribute in the list (a corrupt record) >+ */ >+static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ /* deliberatly the other order */ >+ const char *attrs[] = {"bar", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ >+ /* This should fail the pidgenhole test */ >+ assert_int_equal(ret, -1); >+} >+ >+/* >+ * Test against a record with two attributes, both matching the one >+ * specified attribute in the list (a corrupt record) >+ */ >+static void test_filter_attrs_two_dup_attr_matched_dup(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"bar", "bar", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ >+ /* This does not fail the pidgenhole test */ >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_int_equal(filtered_msg->num_elements, 2); >+ >+ /* Assert that DB order is preserved */ >+ assert_string_equal(filtered_msg->elements[0].name, "bar"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value1)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value1, sizeof(value1)); >+ assert_string_equal(filtered_msg->elements[1].name, "bar"); >+ assert_int_equal(filtered_msg->elements[1].num_values, 1); >+ assert_int_equal(filtered_msg->elements[1].values[0].length, >+ sizeof(value2)); >+ assert_memory_equal(filtered_msg->elements[1].values[0].data, >+ value2, sizeof(value2)); >+} >+ >+/* >+ * Test against a record with two attributes, both matching one of the >+ * specified attributes in the list (a corrupt record) >+ */ >+static void test_filter_attrs_two_dup_attr_matched_one_of_two(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"bar", "foo", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ >+ /* This does not fail the pidgenhole test */ >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_int_equal(filtered_msg->num_elements, 2); >+ >+ /* Assert that DB order is preserved */ >+ assert_string_equal(filtered_msg->elements[0].name, "bar"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value1)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value1, sizeof(value1)); >+ assert_string_equal(filtered_msg->elements[1].name, "bar"); >+ assert_int_equal(filtered_msg->elements[1].num_values, 1); >+ assert_int_equal(filtered_msg->elements[1].values[0].length, >+ sizeof(value2)); >+ assert_memory_equal(filtered_msg->elements[1].values[0].data, >+ value2, sizeof(value2)); >+} >+ >+/* >+ * Test against a record with two attributes against * (but not the >+ * other named attribute) (a corrupt record) >+ */ >+static void test_filter_attrs_two_dup_attr_matched_star(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"*", "foo", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ >+ /* foo and bar are the other order to in attrs */ >+ struct ldb_message_element elements[] = { >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ /* Needed as * implies distinguishedName */ >+ filtered_msg->dn = in.dn; >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ >+ /* This does not fail the pidgenhole test */ >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_int_equal(filtered_msg->num_elements, 3); >+ >+ /* Assert that DB order is preserved */ >+ assert_string_equal(filtered_msg->elements[0].name, "bar"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_int_equal(filtered_msg->elements[0].values[0].length, >+ sizeof(value1)); >+ assert_memory_equal(filtered_msg->elements[0].values[0].data, >+ value1, sizeof(value1)); >+ assert_string_equal(filtered_msg->elements[1].name, "bar"); >+ assert_int_equal(filtered_msg->elements[1].num_values, 1); >+ assert_int_equal(filtered_msg->elements[1].values[0].length, >+ sizeof(value2)); >+ assert_memory_equal(filtered_msg->elements[1].values[0].data, >+ value2, sizeof(value2)); >+ /* >+ * assert the ldb_filter_attrs does not modify filtered_msg.dn >+ * in this case >+ */ >+ assert_ptr_equal(filtered_msg->dn, in.dn); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "distinguishedName", >+ NULL), >+ ldb_dn_get_linearized(in.dn)); >+} >+ >+/* >+ * Test against a record with only one attribute, matching the * in >+ * the list >+ */ >+static void test_filter_attrs_one_attr_matched_star(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"*", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ /* Needed as * implies distinguishedName */ >+ filtered_msg->dn = in.dn; >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 2); >+ >+ /* >+ * assert the ldb_filter_attrs does not modify filtered_msg.dn >+ * in this case >+ */ >+ assert_ptr_equal(filtered_msg->dn, in.dn); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "distinguishedName", >+ NULL), >+ ldb_dn_get_linearized(in.dn)); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "foo", >+ NULL), >+ value); >+} >+ >+/* >+ * Test against a record with two attributes, matching the * in >+ * the list >+ */ >+static void test_filter_attrs_two_attr_matched_star(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"*", NULL}; >+ >+ uint8_t value1[] = "The value.......end"; >+ uint8_t value2[] = "The value..MUST.end"; >+ struct ldb_val value_1 = { >+ .data = value1, >+ .length = (sizeof(value1)) >+ }; >+ struct ldb_val value_2 = { >+ .data = value2, >+ .length = (sizeof(value2)) >+ }; >+ struct ldb_message_element elements[] = { >+ { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }, >+ { >+ .name = "bar", >+ .num_values = 1, >+ .values = &value_2 >+ } >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 2, >+ .elements = elements, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ /* Needed as * implies distinguishedName */ >+ filtered_msg->dn = in.dn; >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 3); >+ >+ /* >+ * assert the ldb_filter_attrs does not modify filtered_msg.dn >+ * in this case >+ */ >+ assert_ptr_equal(filtered_msg->dn, in.dn); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "distinguishedName", >+ NULL), >+ ldb_dn_get_linearized(in.dn)); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "foo", >+ NULL), >+ value1); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "bar", >+ NULL), >+ value2); >+} >+ >+/* >+ * Test against a record with only one attribute, matching the * in >+ * the list, but without the DN being pre-filled. Fails due to need >+ * to contstruct the distinguishedName >+ */ >+static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"*", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, -1); >+} >+ >+/* >+ * Test against a record with only one attribute, matching the * in >+ * the list plus requsesting distinguishedName >+ */ >+static void test_filter_attrs_one_attr_matched_star_dn(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"*", "distinguishedName", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ /* Needed for distinguishedName */ >+ filtered_msg->dn = in.dn; >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 2); >+ >+ /* show that ldb_filter_attrs does not modify in.dn */ >+ assert_ptr_equal(filtered_msg->dn, in.dn); >+ >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "distinguishedName", >+ NULL), >+ ldb_dn_get_linearized(in.dn)); >+ assert_string_equal(ldb_msg_find_attr_as_string(filtered_msg, >+ "foo", >+ NULL), >+ value); >+} >+ >+/* >+ * Test against a record with only one attribute, but returning >+ * distinguishedName from the list (only) >+ */ >+static void test_filter_attrs_one_attr_matched_dn(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {"distinguishedName", NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ /* Needed for distinguishedName */ >+ filtered_msg->dn = in.dn; >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 1); >+ >+ /* show that ldb_filter_attrs does not modify in.dn */ >+ assert_ptr_equal(filtered_msg->dn, in.dn); >+ assert_string_equal(filtered_msg->elements[0].name, "distinguishedName"); >+ assert_int_equal(filtered_msg->elements[0].num_values, 1); >+ assert_string_equal(filtered_msg->elements[0].values[0].data, >+ ldb_dn_get_linearized(in.dn)); >+} >+ >+/* >+ * Test against a record with only one attribute, not matching the >+ * empty attribute list >+ */ >+static void test_filter_attrs_one_attr_empty_list(void **state) >+{ >+ struct ldbtest_ctx *ctx = *state; >+ int ret; >+ >+ struct ldb_message *filtered_msg = ldb_msg_new(ctx); >+ >+ const char *attrs[] = {NULL}; >+ >+ uint8_t value[] = "The value.......end"; >+ struct ldb_val value_1 = { >+ .data = value, >+ .length = (sizeof(value)) >+ }; >+ struct ldb_message_element element_1 = { >+ .name = "foo", >+ .num_values = 1, >+ .values = &value_1 >+ }; >+ struct ldb_message in = { >+ .dn = ldb_dn_new(ctx, ctx->ldb, "dc=samba,dc=org"), >+ .num_elements = 1, >+ .elements = &element_1, >+ }; >+ >+ assert_non_null(in.dn); >+ >+ ret = ldb_filter_attrs(ctx->ldb, >+ &in, >+ attrs, >+ filtered_msg); >+ assert_int_equal(ret, LDB_SUCCESS); >+ assert_non_null(filtered_msg); >+ assert_int_equal(filtered_msg->num_elements, 0); >+ assert_null(filtered_msg->dn); >+ assert_null(filtered_msg->elements); >+} >+ >+int main(int argc, const char **argv) >+{ >+ const struct CMUnitTest tests[] = { >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched_of_many, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_attr_matched_attrs, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_attr_matched_one_attr, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_dup_attr_matched_one_attr, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_dup_attr_matched_dup, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_dup_attr_matched_one_of_two, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_dup_attr_matched_star, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched_star, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_two_attr_matched_star, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched_star_no_dn, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched_star_dn, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_matched_dn, >+ setup, >+ teardown), >+ cmocka_unit_test_setup_teardown( >+ test_filter_attrs_one_attr_empty_list, >+ setup, >+ teardown), >+ }; >+ >+ return cmocka_run_group_tests(tests, NULL, NULL); >+} >diff --git a/lib/ldb/wscript b/lib/ldb/wscript >index a63a6c2171f..f928e2c739c 100644 >--- a/lib/ldb/wscript >+++ b/lib/ldb/wscript >@@ -512,6 +512,11 @@ def build(bld): > deps='cmocka ldb ldb_tdb_err_map', > install=False) > >+ bld.SAMBA_BINARY('ldb_filter_attrs_test', >+ source='tests/ldb_filter_attrs_test.c', >+ deps='cmocka ldb ldb_tdb_err_map', >+ install=False) >+ > bld.SAMBA_BINARY('ldb_key_value_sub_txn_tdb_test', > bld.SUBDIR('ldb_key_value', > '''ldb_kv_search.c >-- >2.17.1 > > >From 11427be15ed6701fb2a15830846b57fe5e62fb42 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 26 Aug 2019 14:48:52 +1200 >Subject: [PATCH 124/376] ldb: use TALLOC_FREE() over talloc_free() in > ldb_filter_attrs() > >This is a macro that sets the pointer to NULL after the talloc_free() >and is part of our standard coding practices. > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 2117789c35fbf6d0ed02f391f17593e11727ec3e) >--- > lib/ldb/common/ldb_pack.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > >diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c >index 1d67622b69e..b5e1fbbc4ff 100644 >--- a/lib/ldb/common/ldb_pack.c >+++ b/lib/ldb/common/ldb_pack.c >@@ -1251,8 +1251,7 @@ int ldb_filter_attrs(struct ldb_context *ldb, > goto failed; > } > } else { >- talloc_free(filtered_msg->elements); >- filtered_msg->elements = NULL; >+ TALLOC_FREE(filtered_msg->elements); > } > > return 0; >-- >2.17.1 > > >From 61a039cc21d845bb4b984929d878dd8cf68839fe Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Mon, 26 Aug 2019 14:50:15 +1200 >Subject: [PATCH 125/376] ldb: Call TALLOC_FREE(filtered_msg->elements) on > ldb_filter_attrs() failure > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Tue Aug 27 01:16:33 UTC 2019 on sn-devel-184 > >(cherry picked from commit 1521a22f4366c86ec955cb9d32b7a758315d8ce0) >--- > lib/ldb/common/ldb_pack.c | 1 + > lib/ldb/tests/ldb_filter_attrs_test.c | 2 ++ > 2 files changed, 3 insertions(+) > >diff --git a/lib/ldb/common/ldb_pack.c b/lib/ldb/common/ldb_pack.c >index b5e1fbbc4ff..e7dd364008a 100644 >--- a/lib/ldb/common/ldb_pack.c >+++ b/lib/ldb/common/ldb_pack.c >@@ -1256,5 +1256,6 @@ int ldb_filter_attrs(struct ldb_context *ldb, > > return 0; > failed: >+ TALLOC_FREE(filtered_msg->elements); > return -1; > } >diff --git a/lib/ldb/tests/ldb_filter_attrs_test.c b/lib/ldb/tests/ldb_filter_attrs_test.c >index d04775879ac..7d555e0da2e 100644 >--- a/lib/ldb/tests/ldb_filter_attrs_test.c >+++ b/lib/ldb/tests/ldb_filter_attrs_test.c >@@ -384,6 +384,7 @@ static void test_filter_attrs_two_dup_attr_matched_one_attr(void **state) > > /* This should fail the pidgenhole test */ > assert_int_equal(ret, -1); >+ assert_null(filtered_msg->elements); > } > > /* >@@ -772,6 +773,7 @@ static void test_filter_attrs_one_attr_matched_star_no_dn(void **state) > attrs, > filtered_msg); > assert_int_equal(ret, -1); >+ assert_null(filtered_msg->elements); > } > > /* >-- >2.17.1 > > >From c71c51dda004a617eaeccb0819b70310de1ebd14 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Fri, 26 Jul 2019 09:49:13 +1200 >Subject: [PATCH 126/376] ldb: don't try to save a value that isn't there > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 54f30f2fe3f03c9640664f9a11260b093fc57a5b) >--- > lib/ldb/common/ldb_dn.c | 47 +++++++++++++++++++++-------------------- > 1 file changed, 24 insertions(+), 23 deletions(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index 9b2fa966e11..a7fb0d9c443 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -697,31 +697,32 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > goto failed; > } > >- /* save last element */ >- if ( t ) { >- /* trim back */ >- d -= (p - t); >- l -= (p - t); >- } >+ if (in_value) { >+ /* save last element */ >+ if ( t ) { >+ /* trim back */ >+ d -= (p - t); >+ l -= (p - t); >+ } >+ >+ *d++ = '\0'; >+ /* >+ * This talloc_memdup() is OK with the >+ * +1 because *d has been set to '\0' >+ * just above. >+ */ >+ dn->components[dn->comp_num].value.length = l; >+ dn->components[dn->comp_num].value.data = >+ (uint8_t *)talloc_memdup(dn->components, dt, l + 1); >+ if ( ! dn->components[dn->comp_num].value.data) { >+ /* ouch */ >+ goto failed; >+ } >+ talloc_set_name_const(dn->components[dn->comp_num].value.data, >+ (const char *)dn->components[dn->comp_num].value.data); > >- *d++ = '\0'; >- /* >- * This talloc_memdup() is OK with the >- * +1 because *d has been set to '\0' >- * just above. >- */ >- dn->components[dn->comp_num].value.length = l; >- dn->components[dn->comp_num].value.data = >- (uint8_t *)talloc_memdup(dn->components, dt, l + 1); >- if ( ! dn->components[dn->comp_num].value.data) { >- /* ouch */ >- goto failed; >+ dn->comp_num++; > } >- talloc_set_name_const(dn->components[dn->comp_num].value.data, >- (const char *)dn->components[dn->comp_num].value.data); >- >- dn->comp_num++; >- > talloc_free(data); > return true; > >-- >2.17.1 > > >From 0f993c094ea242934766761389cecd5ecfd14a37 Mon Sep 17 00:00:00 2001 >From: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Date: Thu, 25 Jul 2019 12:09:16 +1200 >Subject: [PATCH 127/376] ldb: add some dn explode tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit a097ddf65ce56dcd2e0b072b6dd78f512a77a9da) >--- > lib/ldb/tests/test_ldb_dn.c | 70 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 70 insertions(+) > >diff --git a/lib/ldb/tests/test_ldb_dn.c b/lib/ldb/tests/test_ldb_dn.c >index 4965dcef575..7c202399a21 100644 >--- a/lib/ldb/tests/test_ldb_dn.c >+++ b/lib/ldb/tests/test_ldb_dn.c >@@ -23,6 +23,7 @@ > #include <cmocka.h> > > #include <ldb.h> >+#include "ldb_private.h" > > static void test_ldb_dn_add_child_fmt(void **state) > { >@@ -105,12 +106,81 @@ static void test_ldb_dn_add_child_val2(void **state) > > } > >+struct explode_test { >+ const char *strdn; >+ int comp_num; >+ int ext_comp_num; >+ bool special; >+ bool invalid; >+ const char *linearized; >+ const char *ext_linearized; >+ bool explode_result; >+}; >+ >+static void test_ldb_dn_explode(void **state) >+{ >+ size_t i; >+ struct ldb_context *ldb = ldb_init(NULL, NULL); >+ struct explode_test tests[] = { >+ {"A=B", 1, 0, false, false, "A=B", "A=B", true}, >+ {"", 0, 0, false, false, "", "", true}, >+ {" ", -1, -1, false, false, " ", " ", false}, >+ {"<>", 0, 0, false, false, "", NULL, true}, >+ {"<", 0, 0, false, false, "", NULL, true}, >+ {"<><", 0, 0, false, false, "", NULL, true}, >+ {"<><>", 0, 0, false, false, "", NULL, true}, >+ {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true}, >+ {"x=ð¥", 1, 0, false, false, "x=ð¥", "x=ð¥", true}, >+ }; >+ >+ >+ for (i = 0; i < ARRAY_SIZE(tests); i++) { >+ bool result; >+ const char *linear; >+ const char *ext_linear; >+ struct ldb_dn *dn = ldb_dn_new(ldb, ldb, tests[i].strdn); >+ >+ /* >+ * special, invalid, linear, and ext_linear are set before >+ * explode >+ */ >+ fprintf(stderr, "%zu «%s»: ", i, tests[i].strdn); >+ linear = ldb_dn_get_linearized(dn); >+ assert_true((linear == NULL) == (tests[i].linearized == NULL)); >+ assert_string_equal(linear, >+ tests[i].linearized); >+ >+ ext_linear = ldb_dn_get_extended_linearized(ldb, dn, 1); >+ assert_true((ext_linear == NULL) == >+ (tests[i].ext_linearized == NULL)); >+ >+ if (tests[i].ext_linearized != NULL) { >+ assert_string_equal(ext_linear, >+ tests[i].ext_linearized); >+ } >+ assert_true(ldb_dn_is_special(dn) == tests[i].special); >+ assert_true(ldb_dn_is_valid(dn) != tests[i].invalid); >+ >+ /* comp nums are set by explode */ >+ result = ldb_dn_validate(dn); >+ fprintf(stderr, "res %i lin «%s» ext «%s»\n", >+ result, linear, ext_linear); >+ >+ assert_true(result == tests[i].explode_result); >+ assert_int_equal(ldb_dn_get_comp_num(dn), >+ tests[i].comp_num); >+ assert_int_equal(ldb_dn_get_extended_comp_num(dn), >+ tests[i].ext_comp_num); >+ } >+} >+ > int main(void) { > const struct CMUnitTest tests[] = { > cmocka_unit_test(test_ldb_dn_add_child_fmt), > cmocka_unit_test(test_ldb_dn_add_child_fmt2), > cmocka_unit_test(test_ldb_dn_add_child_val), > cmocka_unit_test(test_ldb_dn_add_child_val2), >+ cmocka_unit_test(test_ldb_dn_explode), > }; > > return cmocka_run_group_tests(tests, NULL, NULL); >-- >2.17.1 > > >From 1bc9476be79b994a3a9b0618f23f176e399c5aaa Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 22 Aug 2019 10:59:07 +1200 >Subject: [PATCH 128/376] ldb: Rework all pointer NULL tests to use Samba's > normal style > >Also avoid if () without braces > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 3f290e95c2c133eb2c983ecc984d3dff4809f3d3) >--- > lib/ldb/common/ldb_dn.c | 52 ++++++++++++++++++++++++++--------------- > 1 file changed, 33 insertions(+), 19 deletions(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index a7fb0d9c443..377dd74d9f3 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -298,19 +298,21 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > char *parse_dn; > bool is_index; > >- if ( ! dn || dn->invalid) return false; >+ if (dn == NULL || dn->invalid) { >+ return false; >+ } > >- if (dn->components) { >+ if (dn->components != NULL) { > return true; > } > >- if (dn->ext_linearized) { >+ if (dn->ext_linearized != NULL) { > parse_dn = dn->ext_linearized; > } else { > parse_dn = dn->linearized; > } > >- if ( ! parse_dn ) { >+ if (parse_dn == NULL) { > return false; > } > >@@ -333,13 +335,13 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > /* in the common case we have 3 or more components */ > /* make sure all components are zeroed, other functions depend on it */ > dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3); >- if ( ! dn->components) { >+ if (dn->components == NULL) { > return false; > } > > /* Components data space is allocated here once */ > data = talloc_array(dn->components, char, strlen(parse_dn) + 1); >- if (!data) { >+ if (data == NULL) { > goto failed; > } > >@@ -403,7 +405,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > dn->ext_components = ext_comp; > > ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name); >- if (!ext_syntax) { >+ if (ext_syntax == NULL) { > /* We don't know about this type of extended DN */ > goto failed; > } >@@ -486,7 +488,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > * with spaces trimmed) */ > *d++ = '\0'; > dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt); >- if ( ! dn->components[dn->comp_num].name) { >+ if (dn->components[dn->comp_num].name == NULL) { > /* ouch */ > goto failed; > } >@@ -564,7 +566,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > } > /* ok found value terminator */ > >- if ( t ) { >+ if (t != NULL) { > /* trim back */ > d -= (p - t); > l -= (p - t); >@@ -585,7 +587,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > dn->components[dn->comp_num].value.data = \ > (uint8_t *)talloc_memdup(dn->components, dt, l + 1); > dn->components[dn->comp_num].value.length = l; >- if ( ! dn->components[dn->comp_num].value.data) { >+ if (dn->components[dn->comp_num].value.data == NULL) { > /* ouch ! */ > goto failed; > } >@@ -600,7 +602,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > dn->components, > struct ldb_dn_component, > dn->comp_num + 1); >- if ( ! dn->components) { >+ if (dn->components == NULL) { > /* ouch ! */ > goto failed; > } >@@ -618,7 +620,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > values, which contain a '+' or '=' > which should normally be escaped */ > if (is_index) { >- if ( t ) t = NULL; >+ if (t != NULL) { >+ t = NULL; >+ } > *d++ = *p++; > l++; > break; >@@ -639,7 +643,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > *d++ = *p++; > l++; > >- if ( t ) t = NULL; >+ if (t != NULL) { >+ t = NULL; >+ } > break; > > case '\\': >@@ -653,7 +659,9 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > *d++ = *p++; > l++; > >- if ( t ) t = NULL; >+ if (t != NULL) { >+ t = NULL; >+ } > break; > > default: >@@ -672,14 +680,20 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > > escape = false; > l++; >- if ( t ) t = NULL; >+ if (t != NULL) { >+ t = NULL; >+ } > break; > } > > if (*p == ' ') { >- if ( ! t) t = p; >+ if (t == NULL) { >+ t = p; >+ } > } else { >- if ( t ) t = NULL; >+ if (t != NULL) { >+ t = NULL; >+ } > } > > *d++ = *p++; >@@ -699,7 +713,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > > if (in_value) { > /* save last element */ >- if ( t ) { >+ if (t != NULL) { > /* trim back */ > d -= (p - t); > l -= (p - t); >@@ -714,7 +728,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > dn->components[dn->comp_num].value.length = l; > dn->components[dn->comp_num].value.data = > (uint8_t *)talloc_memdup(dn->components, dt, l + 1); >- if ( ! dn->components[dn->comp_num].value.data) { >+ if (dn->components[dn->comp_num].value.data == NULL) { > /* ouch */ > goto failed; > } >-- >2.17.1 > > >From 9b0c30517834da57a436ac6a0bad1fa2c6173849 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 22 Aug 2019 11:09:55 +1200 >Subject: [PATCH 129/376] ldb: Add test with == true or false to boolean if > statements in ldb_dn_explode() > >This is beyond the normal level of clarity we expect in Samba, and is of course >rudundent, but this is a complex routine that has confusing tests, some of >pointers and some of boolean state values. > >This tries to make the code as clear as possible pending a more comprehensive >rewrite. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 52bd2dde5ae809ecc115f7087e367327f4771e73) >--- > lib/ldb/common/ldb_dn.c | 32 ++++++++++++++++---------------- > 1 file changed, 16 insertions(+), 16 deletions(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index 377dd74d9f3..b9a414dc566 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -298,7 +298,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > char *parse_dn; > bool is_index; > >- if (dn == NULL || dn->invalid) { >+ if (dn == NULL || dn->invalid == true) { > return false; > } > >@@ -324,7 +324,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > } > > /* Special DNs case */ >- if (dn->special) { >+ if (dn->special == true) { > return true; > } > >@@ -350,7 +350,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > d = dt = data; > > while (*p) { >- if (in_extended) { >+ if (in_extended == true) { > > if (!in_ex_name && !in_ex_value) { > >@@ -437,8 +437,8 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > *d++ = *p++; > continue; > } >- if (in_attr) { >- if (trim) { >+ if (in_attr == true) { >+ if (trim == true) { > if (*p == ' ') { > p++; > continue; >@@ -505,7 +505,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > goto failed; > } > >- if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) { >+ if (is_oid == true && ( ! (isdigit(*p) || (*p == '.')))) { > /* not a digit nor a dot, > * invalid attribute oid */ > ldb_dn_mark_invalid(dn); >@@ -521,8 +521,8 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > continue; > } > >- if (in_value) { >- if (in_quote) { >+ if (in_value == true) { >+ if (in_quote == true) { > if (*p == '\"') { > if (p[-1] != '\\') { > p++; >@@ -535,7 +535,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > continue; > } > >- if (trim) { >+ if (trim == true) { > if (*p == ' ') { > p++; > continue; >@@ -558,7 +558,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > */ > > case ',': >- if (escape) { >+ if (escape == true) { > *d++ = *p++; > l++; > escape = false; >@@ -619,7 +619,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > accept the base64 encoded binary index > values, which contain a '+' or '=' > which should normally be escaped */ >- if (is_index) { >+ if (is_index == true) { > if (t != NULL) { > t = NULL; > } >@@ -634,7 +634,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > case '>': > case ';': > /* a string with not escaped specials is invalid (tested) */ >- if ( ! escape) { >+ if (escape == false) { > ldb_dn_mark_invalid(dn); > goto failed; > } >@@ -649,7 +649,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > break; > > case '\\': >- if ( ! escape) { >+ if (escape == false) { > escape = true; > p++; > continue; >@@ -665,7 +665,7 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > break; > > default: >- if (escape) { >+ if (escape == true) { > if (isxdigit(p[0]) && isxdigit(p[1])) { > if (sscanf(p, "%02x", &x) != 1) { > /* invalid escaping sequence */ >@@ -705,13 +705,13 @@ static bool ldb_dn_explode(struct ldb_dn *dn) > } > } > >- if (in_attr || in_quote) { >+ if (in_attr == true || in_quote == true) { > /* invalid dn */ > ldb_dn_mark_invalid(dn); > goto failed; > } > >- if (in_value) { >+ if (in_value == true) { > /* save last element */ > if (t != NULL) { > /* trim back */ >-- >2.17.1 > > >From e019f3a6aac62460ee9768fec4001e00f00f8096 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 27 Aug 2019 13:16:18 +1200 >Subject: [PATCH 130/376] ldb: Do not read beyond the end of the extended DN > component when printing > >The print functions used in Samba NULL terminate, but do not assume they will > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit a8a3cef3a768aaff01227dd7b229fb7b3aef926f) >--- > lib/ldb/common/ldb_dn.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c >index b9a414dc566..83f94e3b913 100644 >--- a/lib/ldb/common/ldb_dn.c >+++ b/lib/ldb/common/ldb_dn.c >@@ -871,11 +871,15 @@ char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int > } > > if (i == 0) { >- p = talloc_asprintf(mem_ctx, "<%s=%s>", >- name, val.data); >+ p = talloc_asprintf(mem_ctx, "<%s=%.*s>", >+ name, >+ (int)val.length, >+ val.data); > } else { >- p = talloc_asprintf_append_buffer(p, ";<%s=%s>", >- name, val.data); >+ p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>", >+ name, >+ (int)val.length, >+ val.data); > } > > talloc_free(val.data); >-- >2.17.1 > > >From 9392ee7d29081118afd2dfd531946cbdcaba729d Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Tue, 27 Aug 2019 13:16:50 +1200 >Subject: [PATCH 131/376] ldb: Extend the ldb_dn_explode test matrix > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14049 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 10058bcfa16d5029e61252d64d142a8aab9ec296) >--- > lib/ldb/tests/test_ldb_dn.c | 53 ++++++++++++++++++++++++++++++++++--- > 1 file changed, 49 insertions(+), 4 deletions(-) > >diff --git a/lib/ldb/tests/test_ldb_dn.c b/lib/ldb/tests/test_ldb_dn.c >index 7c202399a21..05f30e4ac67 100644 >--- a/lib/ldb/tests/test_ldb_dn.c >+++ b/lib/ldb/tests/test_ldb_dn.c >@@ -113,10 +113,42 @@ struct explode_test { > bool special; > bool invalid; > const char *linearized; >- const char *ext_linearized; >+ const char *ext_linearized_1; > bool explode_result; > }; > >+static int extended_dn_read_ID(struct ldb_context *ldb, void *mem_ctx, >+ const struct ldb_val *in, struct ldb_val *out) >+{ >+ >+ /* Allow to check we can cope with validity checks */ >+ if (in->length != 4) { >+ return -1; >+ } >+ >+ *out = *in; >+ out->data = talloc_memdup(mem_ctx, in->data, in->length); >+ if (out->data == NULL) { >+ return -1; >+ } >+ >+ return 0; >+} >+ >+/* write out (resued for both HEX and clear for now) */ >+static int extended_dn_write_ID(struct ldb_context *ldb, void *mem_ctx, >+ const struct ldb_val *in, struct ldb_val *out) >+{ >+ *out = *in; >+ >+ out->data = talloc_memdup(mem_ctx, in->data, in->length); >+ if (out->data == NULL) { >+ return -1; >+ } >+ return 0; >+} >+ >+ > static void test_ldb_dn_explode(void **state) > { > size_t i; >@@ -130,9 +162,22 @@ static void test_ldb_dn_explode(void **state) > {"<><", 0, 0, false, false, "", NULL, true}, > {"<><>", 0, 0, false, false, "", NULL, true}, > {"A=B,C=D", 2, 0, false, false, "A=B,C=D", "A=B,C=D", true}, >+ {"<X=Y>A=B,C=D", -1, -1, false, false, "", NULL, false}, >+ {"<X=Y>;A=B,C=D", -1, -1, false, false, "A=B,C=D", NULL, false}, >+ {"<ID=ABC>;A=B,C=D", -1, -1, false, true, "A=B,C=D", NULL, false}, >+ {"<ID=ABCD>;A=B,C=D", 2, 1, false, false, "A=B,C=D", "<ID=ABCD>;A=B,C=D", true}, > {"x=ð¥", 1, 0, false, false, "x=ð¥", "x=ð¥", true}, >+ {"@FOO", 0, 0, true, false, "@FOO", "@FOO", true}, >+ }; >+ >+ struct ldb_dn_extended_syntax syntax = { >+ .name = "ID", >+ .read_fn = extended_dn_read_ID, >+ .write_clear_fn = extended_dn_write_ID, >+ .write_hex_fn = extended_dn_write_ID > }; > >+ ldb_dn_extended_add_syntax(ldb, 0, &syntax); > > for (i = 0; i < ARRAY_SIZE(tests); i++) { > bool result; >@@ -152,11 +197,11 @@ static void test_ldb_dn_explode(void **state) > > ext_linear = ldb_dn_get_extended_linearized(ldb, dn, 1); > assert_true((ext_linear == NULL) == >- (tests[i].ext_linearized == NULL)); >+ (tests[i].ext_linearized_1 == NULL)); > >- if (tests[i].ext_linearized != NULL) { >+ if (tests[i].ext_linearized_1 != NULL) { > assert_string_equal(ext_linear, >- tests[i].ext_linearized); >+ tests[i].ext_linearized_1); > } > assert_true(ldb_dn_is_special(dn) == tests[i].special); > assert_true(ldb_dn_is_valid(dn) != tests[i].invalid); >-- >2.17.1 > > >From bc0d16c9d8eacd254552ff28726a2ba5f2a1c8c0 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Wed, 28 Aug 2019 17:44:52 +1200 >Subject: [PATCH 132/376] ldb: Release ldb 2.0.7 > >* Robustness improvements against duplicate attributes in ldb_filter_attrs() > (bug 13695) >* Robustness improvements against invalid string DN values (bug 14049) > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Sep 4 10:24:56 UTC 2019 on sn-devel-184 >--- > lib/ldb/ABI/ldb-2.0.7.sigs | 283 ++++++++++++++++++++++++++++++ > lib/ldb/ABI/pyldb-util-2.0.7.sigs | 2 + > lib/ldb/wscript | 2 +- > 3 files changed, 286 insertions(+), 1 deletion(-) > create mode 100644 lib/ldb/ABI/ldb-2.0.7.sigs > create mode 100644 lib/ldb/ABI/pyldb-util-2.0.7.sigs > >diff --git a/lib/ldb/ABI/ldb-2.0.7.sigs b/lib/ldb/ABI/ldb-2.0.7.sigs >new file mode 100644 >index 00000000000..5049dc64ce1 >--- /dev/null >+++ b/lib/ldb/ABI/ldb-2.0.7.sigs >@@ -0,0 +1,283 @@ >+ldb_add: int (struct ldb_context *, const struct ldb_message *) >+ldb_any_comparison: int (struct ldb_context *, void *, ldb_attr_handler_t, const struct ldb_val *, const struct ldb_val *) >+ldb_asprintf_errstring: void (struct ldb_context *, const char *, ...) >+ldb_attr_casefold: char *(TALLOC_CTX *, const char *) >+ldb_attr_dn: int (const char *) >+ldb_attr_in_list: int (const char * const *, const char *) >+ldb_attr_list_copy: const char **(TALLOC_CTX *, const char * const *) >+ldb_attr_list_copy_add: const char **(TALLOC_CTX *, const char * const *, const char *) >+ldb_base64_decode: int (char *) >+ldb_base64_encode: char *(TALLOC_CTX *, const char *, int) >+ldb_binary_decode: struct ldb_val (TALLOC_CTX *, const char *) >+ldb_binary_encode: char *(TALLOC_CTX *, struct ldb_val) >+ldb_binary_encode_string: char *(TALLOC_CTX *, const char *) >+ldb_build_add_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_del_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_extended_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const char *, void *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_mod_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_rename_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, struct ldb_dn *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, const char *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_build_search_req_ex: int (struct ldb_request **, struct ldb_context *, TALLOC_CTX *, struct ldb_dn *, enum ldb_scope, struct ldb_parse_tree *, const char * const *, struct ldb_control **, void *, ldb_request_callback_t, struct ldb_request *) >+ldb_casefold: char *(struct ldb_context *, TALLOC_CTX *, const char *, size_t) >+ldb_casefold_default: char *(void *, TALLOC_CTX *, const char *, size_t) >+ldb_check_critical_controls: int (struct ldb_control **) >+ldb_comparison_binary: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_comparison_fold: int (struct ldb_context *, void *, const struct ldb_val *, const struct ldb_val *) >+ldb_connect: int (struct ldb_context *, const char *, unsigned int, const char **) >+ldb_control_to_string: char *(TALLOC_CTX *, const struct ldb_control *) >+ldb_controls_except_specified: struct ldb_control **(struct ldb_control **, TALLOC_CTX *, struct ldb_control *) >+ldb_debug: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_debug_add: void (struct ldb_context *, const char *, ...) >+ldb_debug_end: void (struct ldb_context *, enum ldb_debug_level) >+ldb_debug_set: void (struct ldb_context *, enum ldb_debug_level, const char *, ...) >+ldb_delete: int (struct ldb_context *, struct ldb_dn *) >+ldb_dn_add_base: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_base_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_add_child_fmt: bool (struct ldb_dn *, const char *, ...) >+ldb_dn_add_child_val: bool (struct ldb_dn *, const char *, struct ldb_val) >+ldb_dn_alloc_casefold: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_alloc_linearized: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_ex_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_canonical_string: char *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_check_local: bool (struct ldb_module *, struct ldb_dn *) >+ldb_dn_check_special: bool (struct ldb_dn *, const char *) >+ldb_dn_compare: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_compare_base: int (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_copy: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_escape_value: char *(TALLOC_CTX *, struct ldb_val) >+ldb_dn_extended_add_syntax: int (struct ldb_context *, unsigned int, const struct ldb_dn_extended_syntax *) >+ldb_dn_extended_filter: void (struct ldb_dn *, const char * const *) >+ldb_dn_extended_syntax_by_name: const struct ldb_dn_extended_syntax *(struct ldb_context *, const char *) >+ldb_dn_from_ldb_val: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const struct ldb_val *) >+ldb_dn_get_casefold: const char *(struct ldb_dn *) >+ldb_dn_get_comp_num: int (struct ldb_dn *) >+ldb_dn_get_component_name: const char *(struct ldb_dn *, unsigned int) >+ldb_dn_get_component_val: const struct ldb_val *(struct ldb_dn *, unsigned int) >+ldb_dn_get_extended_comp_num: int (struct ldb_dn *) >+ldb_dn_get_extended_component: const struct ldb_val *(struct ldb_dn *, const char *) >+ldb_dn_get_extended_linearized: char *(TALLOC_CTX *, struct ldb_dn *, int) >+ldb_dn_get_ldb_context: struct ldb_context *(struct ldb_dn *) >+ldb_dn_get_linearized: const char *(struct ldb_dn *) >+ldb_dn_get_parent: struct ldb_dn *(TALLOC_CTX *, struct ldb_dn *) >+ldb_dn_get_rdn_name: const char *(struct ldb_dn *) >+ldb_dn_get_rdn_val: const struct ldb_val *(struct ldb_dn *) >+ldb_dn_has_extended: bool (struct ldb_dn *) >+ldb_dn_is_null: bool (struct ldb_dn *) >+ldb_dn_is_special: bool (struct ldb_dn *) >+ldb_dn_is_valid: bool (struct ldb_dn *) >+ldb_dn_map_local: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_rebase_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_map_remote: struct ldb_dn *(struct ldb_module *, void *, struct ldb_dn *) >+ldb_dn_minimise: bool (struct ldb_dn *) >+ldb_dn_new: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *) >+ldb_dn_new_fmt: struct ldb_dn *(TALLOC_CTX *, struct ldb_context *, const char *, ...) >+ldb_dn_remove_base_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_child_components: bool (struct ldb_dn *, unsigned int) >+ldb_dn_remove_extended_components: void (struct ldb_dn *) >+ldb_dn_replace_components: bool (struct ldb_dn *, struct ldb_dn *) >+ldb_dn_set_component: int (struct ldb_dn *, int, const char *, const struct ldb_val) >+ldb_dn_set_extended_component: int (struct ldb_dn *, const char *, const struct ldb_val *) >+ldb_dn_update_components: int (struct ldb_dn *, const struct ldb_dn *) >+ldb_dn_validate: bool (struct ldb_dn *) >+ldb_dump_results: void (struct ldb_context *, struct ldb_result *, FILE *) >+ldb_error_at: int (struct ldb_context *, int, const char *, const char *, int) >+ldb_errstring: const char *(struct ldb_context *) >+ldb_extended: int (struct ldb_context *, const char *, void *, struct ldb_result **) >+ldb_extended_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_filter_attrs: int (struct ldb_context *, const struct ldb_message *, const char * const *, struct ldb_message *) >+ldb_filter_from_tree: char *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_get_config_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_create_perms: unsigned int (struct ldb_context *) >+ldb_get_default_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_event_context: struct tevent_context *(struct ldb_context *) >+ldb_get_flags: unsigned int (struct ldb_context *) >+ldb_get_opaque: void *(struct ldb_context *, const char *) >+ldb_get_root_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_get_schema_basedn: struct ldb_dn *(struct ldb_context *) >+ldb_global_init: int (void) >+ldb_handle_get_event_context: struct tevent_context *(struct ldb_handle *) >+ldb_handle_new: struct ldb_handle *(TALLOC_CTX *, struct ldb_context *) >+ldb_handle_use_global_event_context: void (struct ldb_handle *) >+ldb_handler_copy: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_handler_fold: int (struct ldb_context *, void *, const struct ldb_val *, struct ldb_val *) >+ldb_init: struct ldb_context *(TALLOC_CTX *, struct tevent_context *) >+ldb_ldif_message_redacted_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_message_string: char *(struct ldb_context *, TALLOC_CTX *, enum ldb_changetype, const struct ldb_message *) >+ldb_ldif_parse_modrdn: int (struct ldb_context *, const struct ldb_ldif *, TALLOC_CTX *, struct ldb_dn **, struct ldb_dn **, bool *, struct ldb_dn **, struct ldb_dn **) >+ldb_ldif_read: struct ldb_ldif *(struct ldb_context *, int (*)(void *), void *) >+ldb_ldif_read_file: struct ldb_ldif *(struct ldb_context *, FILE *) >+ldb_ldif_read_file_state: struct ldb_ldif *(struct ldb_context *, struct ldif_read_file_state *) >+ldb_ldif_read_free: void (struct ldb_context *, struct ldb_ldif *) >+ldb_ldif_read_string: struct ldb_ldif *(struct ldb_context *, const char **) >+ldb_ldif_write: int (struct ldb_context *, int (*)(void *, const char *, ...), void *, const struct ldb_ldif *) >+ldb_ldif_write_file: int (struct ldb_context *, FILE *, const struct ldb_ldif *) >+ldb_ldif_write_redacted_trace_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_ldif_write_string: char *(struct ldb_context *, TALLOC_CTX *, const struct ldb_ldif *) >+ldb_load_modules: int (struct ldb_context *, const char **) >+ldb_map_add: int (struct ldb_module *, struct ldb_request *) >+ldb_map_delete: int (struct ldb_module *, struct ldb_request *) >+ldb_map_init: int (struct ldb_module *, const struct ldb_map_attribute *, const struct ldb_map_objectclass *, const char * const *, const char *, const char *) >+ldb_map_modify: int (struct ldb_module *, struct ldb_request *) >+ldb_map_rename: int (struct ldb_module *, struct ldb_request *) >+ldb_map_search: int (struct ldb_module *, struct ldb_request *) >+ldb_match_message: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, enum ldb_scope, bool *) >+ldb_match_msg: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope) >+ldb_match_msg_error: int (struct ldb_context *, const struct ldb_message *, const struct ldb_parse_tree *, struct ldb_dn *, enum ldb_scope, bool *) >+ldb_match_msg_objectclass: int (const struct ldb_message *, const char *) >+ldb_mod_register_control: int (struct ldb_module *, const char *) >+ldb_modify: int (struct ldb_context *, const struct ldb_message *) >+ldb_modify_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_module_call_chain: char *(struct ldb_request *, TALLOC_CTX *) >+ldb_module_connect_backend: int (struct ldb_context *, const char *, const char **, struct ldb_module **) >+ldb_module_done: int (struct ldb_request *, struct ldb_control **, struct ldb_extended *, int) >+ldb_module_flags: uint32_t (struct ldb_context *) >+ldb_module_get_ctx: struct ldb_context *(struct ldb_module *) >+ldb_module_get_name: const char *(struct ldb_module *) >+ldb_module_get_ops: const struct ldb_module_ops *(struct ldb_module *) >+ldb_module_get_private: void *(struct ldb_module *) >+ldb_module_init_chain: int (struct ldb_context *, struct ldb_module *) >+ldb_module_load_list: int (struct ldb_context *, const char **, struct ldb_module *, struct ldb_module **) >+ldb_module_new: struct ldb_module *(TALLOC_CTX *, struct ldb_context *, const char *, const struct ldb_module_ops *) >+ldb_module_next: struct ldb_module *(struct ldb_module *) >+ldb_module_popt_options: struct poptOption **(struct ldb_context *) >+ldb_module_send_entry: int (struct ldb_request *, struct ldb_message *, struct ldb_control **) >+ldb_module_send_referral: int (struct ldb_request *, char *) >+ldb_module_set_next: void (struct ldb_module *, struct ldb_module *) >+ldb_module_set_private: void (struct ldb_module *, void *) >+ldb_modules_hook: int (struct ldb_context *, enum ldb_module_hook_type) >+ldb_modules_list_from_string: const char **(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_modules_load: int (const char *, const char *) >+ldb_msg_add: int (struct ldb_message *, const struct ldb_message_element *, int) >+ldb_msg_add_empty: int (struct ldb_message *, const char *, int, struct ldb_message_element **) >+ldb_msg_add_fmt: int (struct ldb_message *, const char *, const char *, ...) >+ldb_msg_add_linearized_dn: int (struct ldb_message *, const char *, struct ldb_dn *) >+ldb_msg_add_steal_string: int (struct ldb_message *, const char *, char *) >+ldb_msg_add_steal_value: int (struct ldb_message *, const char *, struct ldb_val *) >+ldb_msg_add_string: int (struct ldb_message *, const char *, const char *) >+ldb_msg_add_value: int (struct ldb_message *, const char *, const struct ldb_val *, struct ldb_message_element **) >+ldb_msg_canonicalize: struct ldb_message *(struct ldb_context *, const struct ldb_message *) >+ldb_msg_check_string_attribute: int (const struct ldb_message *, const char *, const char *) >+ldb_msg_copy: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_copy_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_copy_shallow: struct ldb_message *(TALLOC_CTX *, const struct ldb_message *) >+ldb_msg_diff: struct ldb_message *(struct ldb_context *, struct ldb_message *, struct ldb_message *) >+ldb_msg_difference: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message *, struct ldb_message *, struct ldb_message **) >+ldb_msg_element_compare: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_compare_name: int (struct ldb_message_element *, struct ldb_message_element *) >+ldb_msg_element_equal_ordered: bool (const struct ldb_message_element *, const struct ldb_message_element *) >+ldb_msg_find_attr_as_bool: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_dn: struct ldb_dn *(struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, const char *) >+ldb_msg_find_attr_as_double: double (const struct ldb_message *, const char *, double) >+ldb_msg_find_attr_as_int: int (const struct ldb_message *, const char *, int) >+ldb_msg_find_attr_as_int64: int64_t (const struct ldb_message *, const char *, int64_t) >+ldb_msg_find_attr_as_string: const char *(const struct ldb_message *, const char *, const char *) >+ldb_msg_find_attr_as_uint: unsigned int (const struct ldb_message *, const char *, unsigned int) >+ldb_msg_find_attr_as_uint64: uint64_t (const struct ldb_message *, const char *, uint64_t) >+ldb_msg_find_common_values: int (struct ldb_context *, TALLOC_CTX *, struct ldb_message_element *, struct ldb_message_element *, uint32_t) >+ldb_msg_find_duplicate_val: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message_element *, struct ldb_val **, uint32_t) >+ldb_msg_find_element: struct ldb_message_element *(const struct ldb_message *, const char *) >+ldb_msg_find_ldb_val: const struct ldb_val *(const struct ldb_message *, const char *) >+ldb_msg_find_val: struct ldb_val *(const struct ldb_message_element *, struct ldb_val *) >+ldb_msg_new: struct ldb_message *(TALLOC_CTX *) >+ldb_msg_normalize: int (struct ldb_context *, TALLOC_CTX *, const struct ldb_message *, struct ldb_message **) >+ldb_msg_remove_attr: void (struct ldb_message *, const char *) >+ldb_msg_remove_element: void (struct ldb_message *, struct ldb_message_element *) >+ldb_msg_rename_attr: int (struct ldb_message *, const char *, const char *) >+ldb_msg_sanity_check: int (struct ldb_context *, const struct ldb_message *) >+ldb_msg_sort_elements: void (struct ldb_message *) >+ldb_next_del_trans: int (struct ldb_module *) >+ldb_next_end_trans: int (struct ldb_module *) >+ldb_next_init: int (struct ldb_module *) >+ldb_next_prepare_commit: int (struct ldb_module *) >+ldb_next_read_lock: int (struct ldb_module *) >+ldb_next_read_unlock: int (struct ldb_module *) >+ldb_next_remote_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_request: int (struct ldb_module *, struct ldb_request *) >+ldb_next_start_trans: int (struct ldb_module *) >+ldb_op_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_options_copy: const char **(TALLOC_CTX *, const char **) >+ldb_options_find: const char *(struct ldb_context *, const char **, const char *) >+ldb_options_get: const char **(struct ldb_context *) >+ldb_pack_data: int (struct ldb_context *, const struct ldb_message *, struct ldb_val *, uint32_t) >+ldb_parse_control_from_string: struct ldb_control *(struct ldb_context *, TALLOC_CTX *, const char *) >+ldb_parse_control_strings: struct ldb_control **(struct ldb_context *, TALLOC_CTX *, const char **) >+ldb_parse_tree: struct ldb_parse_tree *(TALLOC_CTX *, const char *) >+ldb_parse_tree_attr_replace: void (struct ldb_parse_tree *, const char *, const char *) >+ldb_parse_tree_copy_shallow: struct ldb_parse_tree *(TALLOC_CTX *, const struct ldb_parse_tree *) >+ldb_parse_tree_walk: int (struct ldb_parse_tree *, int (*)(struct ldb_parse_tree *, void *), void *) >+ldb_qsort: void (void * const, size_t, size_t, void *, ldb_qsort_cmp_fn_t) >+ldb_register_backend: int (const char *, ldb_connect_fn, bool) >+ldb_register_extended_match_rule: int (struct ldb_context *, const struct ldb_extended_match_rule *) >+ldb_register_hook: int (ldb_hook_fn) >+ldb_register_module: int (const struct ldb_module_ops *) >+ldb_rename: int (struct ldb_context *, struct ldb_dn *, struct ldb_dn *) >+ldb_reply_add_control: int (struct ldb_reply *, const char *, bool, void *) >+ldb_reply_get_control: struct ldb_control *(struct ldb_reply *, const char *) >+ldb_req_get_custom_flags: uint32_t (struct ldb_request *) >+ldb_req_is_untrusted: bool (struct ldb_request *) >+ldb_req_location: const char *(struct ldb_request *) >+ldb_req_mark_trusted: void (struct ldb_request *) >+ldb_req_mark_untrusted: void (struct ldb_request *) >+ldb_req_set_custom_flags: void (struct ldb_request *, uint32_t) >+ldb_req_set_location: void (struct ldb_request *, const char *) >+ldb_request: int (struct ldb_context *, struct ldb_request *) >+ldb_request_add_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_done: int (struct ldb_request *, int) >+ldb_request_get_control: struct ldb_control *(struct ldb_request *, const char *) >+ldb_request_get_status: int (struct ldb_request *) >+ldb_request_replace_control: int (struct ldb_request *, const char *, bool, void *) >+ldb_request_set_state: void (struct ldb_request *, int) >+ldb_reset_err_string: void (struct ldb_context *) >+ldb_save_controls: int (struct ldb_control *, struct ldb_request *, struct ldb_control ***) >+ldb_schema_attribute_add: int (struct ldb_context *, const char *, unsigned int, const char *) >+ldb_schema_attribute_add_with_syntax: int (struct ldb_context *, const char *, unsigned int, const struct ldb_schema_syntax *) >+ldb_schema_attribute_by_name: const struct ldb_schema_attribute *(struct ldb_context *, const char *) >+ldb_schema_attribute_fill_with_syntax: int (struct ldb_context *, TALLOC_CTX *, const char *, unsigned int, const struct ldb_schema_syntax *, struct ldb_schema_attribute *) >+ldb_schema_attribute_remove: void (struct ldb_context *, const char *) >+ldb_schema_attribute_remove_flagged: void (struct ldb_context *, unsigned int) >+ldb_schema_attribute_set_override_handler: void (struct ldb_context *, ldb_attribute_handler_override_fn_t, void *) >+ldb_schema_set_override_GUID_index: void (struct ldb_context *, const char *, const char *) >+ldb_schema_set_override_indexlist: void (struct ldb_context *, bool) >+ldb_search: int (struct ldb_context *, TALLOC_CTX *, struct ldb_result **, struct ldb_dn *, enum ldb_scope, const char * const *, const char *, ...) >+ldb_search_default_callback: int (struct ldb_request *, struct ldb_reply *) >+ldb_sequence_number: int (struct ldb_context *, enum ldb_sequence_type, uint64_t *) >+ldb_set_create_perms: void (struct ldb_context *, unsigned int) >+ldb_set_debug: int (struct ldb_context *, void (*)(void *, enum ldb_debug_level, const char *, va_list), void *) >+ldb_set_debug_stderr: int (struct ldb_context *) >+ldb_set_default_dns: void (struct ldb_context *) >+ldb_set_errstring: void (struct ldb_context *, const char *) >+ldb_set_event_context: void (struct ldb_context *, struct tevent_context *) >+ldb_set_flags: void (struct ldb_context *, unsigned int) >+ldb_set_modules_dir: void (struct ldb_context *, const char *) >+ldb_set_opaque: int (struct ldb_context *, const char *, void *) >+ldb_set_require_private_event_context: void (struct ldb_context *) >+ldb_set_timeout: int (struct ldb_context *, struct ldb_request *, int) >+ldb_set_timeout_from_prev_req: int (struct ldb_context *, struct ldb_request *, struct ldb_request *) >+ldb_set_utf8_default: void (struct ldb_context *) >+ldb_set_utf8_fns: void (struct ldb_context *, void *, char *(*)(void *, void *, const char *, size_t)) >+ldb_setup_wellknown_attributes: int (struct ldb_context *) >+ldb_should_b64_encode: int (struct ldb_context *, const struct ldb_val *) >+ldb_standard_syntax_by_name: const struct ldb_schema_syntax *(struct ldb_context *, const char *) >+ldb_strerror: const char *(int) >+ldb_string_to_time: time_t (const char *) >+ldb_string_utc_to_time: time_t (const char *) >+ldb_timestring: char *(TALLOC_CTX *, time_t) >+ldb_timestring_utc: char *(TALLOC_CTX *, time_t) >+ldb_transaction_cancel: int (struct ldb_context *) >+ldb_transaction_cancel_noerr: int (struct ldb_context *) >+ldb_transaction_commit: int (struct ldb_context *) >+ldb_transaction_prepare_commit: int (struct ldb_context *) >+ldb_transaction_start: int (struct ldb_context *) >+ldb_unpack_data: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *) >+ldb_unpack_data_flags: int (struct ldb_context *, const struct ldb_val *, struct ldb_message *, unsigned int) >+ldb_unpack_get_format: int (const struct ldb_val *, uint32_t *) >+ldb_val_dup: struct ldb_val (TALLOC_CTX *, const struct ldb_val *) >+ldb_val_equal_exact: int (const struct ldb_val *, const struct ldb_val *) >+ldb_val_map_local: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_map_remote: struct ldb_val (struct ldb_module *, void *, const struct ldb_map_attribute *, const struct ldb_val *) >+ldb_val_string_cmp: int (const struct ldb_val *, const char *) >+ldb_val_to_time: int (const struct ldb_val *, time_t *) >+ldb_valid_attr_name: int (const char *) >+ldb_vdebug: void (struct ldb_context *, enum ldb_debug_level, const char *, va_list) >+ldb_wait: int (struct ldb_handle *, enum ldb_wait_type) >diff --git a/lib/ldb/ABI/pyldb-util-2.0.7.sigs b/lib/ldb/ABI/pyldb-util-2.0.7.sigs >new file mode 100644 >index 00000000000..74d6719d2bc >--- /dev/null >+++ b/lib/ldb/ABI/pyldb-util-2.0.7.sigs >@@ -0,0 +1,2 @@ >+pyldb_Dn_FromDn: PyObject *(struct ldb_dn *) >+pyldb_Object_AsDn: bool (TALLOC_CTX *, PyObject *, struct ldb_context *, struct ldb_dn **) >diff --git a/lib/ldb/wscript b/lib/ldb/wscript >index f928e2c739c..750306fbddb 100644 >--- a/lib/ldb/wscript >+++ b/lib/ldb/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'ldb' >-VERSION = '2.0.6' >+VERSION = '2.0.7' > > import sys, os > >-- >2.17.1 > > >From 116f8cfe3041676264f2bfa2ca43d6266cb326ab Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 5 Sep 2019 11:23:22 +1200 >Subject: [PATCH 133/376] docs: Deprecate "lanman auth = yes" > >This feature is only available for SMB1 and we need to warn users that this >is going away soon, and allow the removal in a future release under our rules >for parameter deprecation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14117 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Thu Sep 5 04:04:18 UTC 2019 on sn-devel-184 > >(cherry picked from commit 1006f7abe8980d2c01c181db93225353ce494b3a) >--- > docs-xml/smbdotconf/security/lanmanauth.xml | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/docs-xml/smbdotconf/security/lanmanauth.xml b/docs-xml/smbdotconf/security/lanmanauth.xml >index 97f2fb04dcb..e5e63e43076 100644 >--- a/docs-xml/smbdotconf/security/lanmanauth.xml >+++ b/docs-xml/smbdotconf/security/lanmanauth.xml >@@ -2,8 +2,17 @@ > context="G" > type="boolean" > function="_lanman_auth" >+ deprecated="1" > xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> > <description> >+ <para>This parameter has been deprecated since Samba 4.11 and >+ support for LanMan (as distinct from NTLM, NTLMv2 or >+ Kerberos authentication) >+ will be removed in a future Samba release.</para> >+ <para>That is, in the future, the current default of >+ <command>lanman auth = no</command> >+ will be the enforced behaviour.</para> >+ > <para>This parameter determines whether or not <citerefentry><refentrytitle>smbd</refentrytitle> > <manvolnum>8</manvolnum></citerefentry> will attempt to > authenticate users or permit password changes >-- >2.17.1 > > >From f1d2b5eba72df50f98860557e3d3523b1e82f625 Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 5 Sep 2019 11:19:10 +1200 >Subject: [PATCH 134/376] docs: Deprecate "encrypt passwords = no" > >This feature is only available for SMB1 and we need to warn users that this >is going away soon, and allow the removal in a future release under our rules >for parameter deprecation. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14117 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Garming Sam <garming@catalyst.net.nz> >(cherry picked from commit 8d0d99a4d78ba408bb45e2d693049025e60e277a) >--- > docs-xml/smbdotconf/security/encryptpasswords.xml | 8 ++++++++ > 1 file changed, 8 insertions(+) > >diff --git a/docs-xml/smbdotconf/security/encryptpasswords.xml b/docs-xml/smbdotconf/security/encryptpasswords.xml >index 4bd97809d86..4fdfa898501 100644 >--- a/docs-xml/smbdotconf/security/encryptpasswords.xml >+++ b/docs-xml/smbdotconf/security/encryptpasswords.xml >@@ -1,8 +1,16 @@ > <samba:parameter name="encrypt passwords" > context="G" > type="boolean" >+ deprecated="1" > xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> > <description> >+ <para>This parameter has been deprecated since Samba 4.11 and >+ support for plaintext (as distinct from NTLM, NTLMv2 >+ or Kerberos authentication) >+ will be removed in a future Samba release.</para> >+ <para>That is, in the future, the current default of >+ <command>encrypt passwords = yes</command> >+ will be the enforced behaviour.</para> > <para>This boolean controls whether encrypted passwords > will be negotiated with the client. Note that Windows NT 4.0 SP3 and > above and also Windows 98 will by default expect encrypted passwords >-- >2.17.1 > > >From 04867f4c513c70313f71c59ed3131307c0d1c4dc Mon Sep 17 00:00:00 2001 >From: Andrew Bartlett <abartlet@samba.org> >Date: Thu, 5 Sep 2019 16:12:10 +1200 >Subject: [PATCH 135/376] WHATSNEW: Add entry for deprecation of "lanman auth" > and "encrypt passwords = no" > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14117 > >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >--- > WHATSNEW.txt | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index eece43fcd9e..904db5fefc3 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -68,6 +68,18 @@ in the following years. If you have a strong requirement for SMB1 > (except for supporting old Linux Kernels), please file a bug > at https://bugzilla.samba.org and let us know about the details. > >+LanMan and plaintext authentication deprecated >+---------------------------------------------- >+ >+The "lanman auth" and "encrypt passwords" parameters are deprecated >+with this release as both are only applicable to SMB1 and are quite >+insecure. NTLM, NTLMv2 and Kerberos authentication are unaffected, as >+"encrypt passwords = yes" has been the default since Samba 3.0.0. >+ >+If you have a strong requirement for these authentication protocols, >+please file a bug at https://bugzilla.samba.org and let us know about >+the details. >+ > BIND9_FLATFILE deprecated > ------------------------- > >@@ -357,6 +369,8 @@ smb.conf changes > fruit:zero_file_id Changed default False > debug encryption New: dump encryption keys False > rndc command Deprecated >+ lanman auth Deprecated >+ encrypt passwords Deprecated > > > CHANGES SINCE 4.11.0rc2 >-- >2.17.1 > > >From 11c2b21b97d2d8fcd46c7e3ac8005e940869bc51 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 12 Jul 2019 10:49:13 +0200 >Subject: [PATCH 136/376] ctdb: fix compilation on systems with glibc robust > mutexes > >On older systems like SLES 11 without POSIX robust mutexes, but with glib robust >mutexes where all the functions are available but have a "_np" suffix, >compilation fails in: > >ctdb/tests/src/test_mutex_raw.c.239.o: In function `worker': >/root/samba-4.10.6/bin/default/../../ctdb/tests/src/test_mutex_raw.c:129: undefined reference to `pthread_mutex_consistent' >ctdb/tests/src/test_mutex_raw.c.239.o: In function `main': >/root/samba-4.10.6/bin/default/../../ctdb/tests/src/test_mutex_raw.c:285: undefined reference to `pthread_mutex_consistent' >/root/samba-4.10.6/bin/default/../../ctdb/tests/src/test_mutex_raw.c:332: undefined reference to `pthread_mutexattr_setrobust' >/root/samba-4.10.6/bin/default/../../ctdb/tests/src/test_mutex_raw.c:363: undefined reference to `pthread_mutex_consistent' >collect2: ld returned 1 exit status > >This could be fixed by using libreplace system/threads.h instead of pthreads.h >directly, but as there has been a desire to keep test_mutex_raw.c standalone and >compilable without other external depenencies then libc and libpthread, make the >tool developer build only. This should get the average user over the cliff. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14038 >RN: Fix compiling ctdb on older systems lacking POSIX robust mutexes > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Martin Schwenke <martin@meltin.net> >(cherry picked from commit f5388f97792ac2d7962950dad91aaf8ad49bceaa) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Fri Sep 6 08:19:44 UTC 2019 on sn-devel-184 >--- > ctdb/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/ctdb/wscript b/ctdb/wscript >index 51a09fdc63d..9663213a2a8 100644 >--- a/ctdb/wscript >+++ b/ctdb/wscript >@@ -1040,7 +1040,7 @@ def build(bld): > ib_deps, > install_path='${CTDB_TEST_LIBEXECDIR}') > >- if bld.env.HAVE_ROBUST_MUTEXES and sys.platform.startswith('linux'): >+ if bld.env.HAVE_ROBUST_MUTEXES and sys.platform.startswith('linux') and bld.env.DEVELOPER: > bld.SAMBA_BINARY('test_mutex_raw', > source='tests/src/test_mutex_raw.c', > deps='pthread', >-- >2.17.1 > > >From bff4ee33420557c6b80646a94de926d4f4c0f24d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 25 Jul 2019 14:37:31 +0200 >Subject: [PATCH 137/376] libcli/smb: add new COMPRESSION and NETNAME negotiate > context ids > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14055 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Aurelien Aptel <aaptel@suse.com> >(cherry picked from commit e10b90f33bb812600886656a1124e2d434416563) >--- > libcli/smb/smb2_constants.h | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h >index 3dd462cdd69..1430f02689c 100644 >--- a/libcli/smb/smb2_constants.h >+++ b/libcli/smb/smb2_constants.h >@@ -131,6 +131,8 @@ > /* Types of SMB2 Negotiate Contexts - only in dialect >= 0x310 */ > #define SMB2_PREAUTH_INTEGRITY_CAPABILITIES 0x0001 > #define SMB2_ENCRYPTION_CAPABILITIES 0x0002 >+#define SMB2_COMPRESSION_CAPABILITIES 0x0003 >+#define SMB2_NETNAME_NEGOTIATE_CONTEXT_ID 0x0005 > > /* Values for the SMB2_PREAUTH_INTEGRITY_CAPABILITIES Context (>= 0x310) */ > #define SMB2_PREAUTH_INTEGRITY_SHA512 0x0001 >-- >2.17.1 > > >From d01dbe68cdfcd873f53c02c9529a944bf209c58f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 25 Jul 2019 14:38:26 +0200 >Subject: [PATCH 138/376] libcli/smb: send SMB2_NETNAME_NEGOTIATE_CONTEXT_ID > >Note: Unlike the current documentation, the utf16 string >is not null-terminated, that matches Windows Server 1903 >as a client. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14055 >RN: Add the target server name of SMB 3.1.1 connections >as a hint to load balancers or servers with "multi-tenancy" >support. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Aurelien Aptel <aaptel@suse.com> >(cherry picked from commit 21f6cece543dd791e0f4636458bfe9819823420c) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Mon Sep 9 12:03:55 UTC 2019 on sn-devel-184 >--- > libcli/smb/smbXcli_base.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > >diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c >index 2f5fac08128..c9b396106ae 100644 >--- a/libcli/smb/smbXcli_base.c >+++ b/libcli/smb/smbXcli_base.c >@@ -4770,6 +4770,8 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta > if (state->conn->max_protocol >= PROTOCOL_SMB3_10) { > NTSTATUS status; > struct smb2_negotiate_contexts c = { .num_contexts = 0, }; >+ uint8_t *netname_utf16 = NULL; >+ size_t netname_utf16_len = 0; > uint32_t offset; > DATA_BLOB b; > uint8_t p[38]; >@@ -4802,6 +4804,21 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta > return NULL; > } > >+ ok = convert_string_talloc(state, CH_UNIX, CH_UTF16, >+ state->conn->remote_name, >+ strlen(state->conn->remote_name), >+ &netname_utf16, &netname_utf16_len); >+ if (!ok) { >+ return NULL; >+ } >+ >+ status = smb2_negotiate_context_add(state, &c, >+ SMB2_NETNAME_NEGOTIATE_CONTEXT_ID, >+ netname_utf16, netname_utf16_len); >+ if (!NT_STATUS_IS_OK(status)) { >+ return NULL; >+ } >+ > status = smb2_negotiate_context_push(state, &b, c); > if (!NT_STATUS_IS_OK(status)) { > return NULL; >-- >2.17.1 > > >From 728e29d84ca594a5607f072e50de60deaa9da45e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Sep 2019 12:50:06 +0200 >Subject: [PATCH 139/376] s3:blocking: call change_to_user_by_fsp() when > dbwrap_watched_watch* finishes > >This is not strictly required as fd-based calls are used, >but it's more consistent to call SMB_VFS_BRL_LOCK_WINDOWS() >in the same environment on retry. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 28ac2cbaf92a8619f0380f024c5a220d9fdc4622) >--- > source3/smbd/blocking.c | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index ffc3142b74c..ca8a625ba9d 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -334,6 +334,15 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) > NTSTATUS status; > bool ok; > >+ /* >+ * Make sure we run as the user again >+ */ >+ ok = change_to_user_by_fsp(state->fsp); >+ if (!ok) { >+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >+ return; >+ } >+ > status = dbwrap_watched_watch_recv(subreq, NULL, NULL); > TALLOC_FREE(subreq); > >-- >2.17.1 > > >From 80a04a4e19adfe87c5217d75b11e41763f644749 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 4 Sep 2019 12:47:07 +0200 >Subject: [PATCH 140/376] s3:smb2_lock: call change_to_user_by_fsp() when > dbwrap_watched_watch* finishes > >This is not strictly required as fd-based calls are used, >but it's more consistent to call SMB_VFS_BRL_LOCK_WINDOWS() >in the same environment on retry. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8b565de1acb0fda121cb0bd4cff42d66ee027529) >--- > source3/smbd/smb2_lock.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 36ec36301b1..e9c8d7f890e 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -421,6 +421,16 @@ static void smbd_smb2_lock_retry(struct tevent_req *subreq) > struct server_id blocking_pid = { 0 }; > uint64_t blocking_smblctx; > NTSTATUS status; >+ bool ok; >+ >+ /* >+ * Make sure we run as the user again >+ */ >+ ok = change_to_user_by_fsp(state->fsp); >+ if (!ok) { >+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >+ return; >+ } > > status = dbwrap_watched_watch_recv(subreq, NULL, NULL); > TALLOC_FREE(subreq); >-- >2.17.1 > > >From 244ad1210cc29ede25fb8692bae46aab7d6725ac Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Sep 2019 08:43:32 +0200 >Subject: [PATCH 141/376] s3:locking: add/split out > byte_range_{valid,overlap}() helper functions > >They implement the logic from [MS-FSA]. > >The following commits will use these functions in other locations. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 0e5613e39d6c6bb892fed939c63b4f14b878803b) >--- > source3/locking/brlock.c | 109 +++++++++++++++++++++++++++++++++------ > source3/locking/proto.h | 6 +++ > 2 files changed, 99 insertions(+), 16 deletions(-) > >diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c >index cdfd09ceff1..628c2574357 100644 >--- a/source3/locking/brlock.c >+++ b/source3/locking/brlock.c >@@ -96,6 +96,92 @@ static bool brl_same_context(const struct lock_context *ctx1, > (ctx1->tid == ctx2->tid)); > } > >+bool byte_range_valid(uint64_t ofs, uint64_t len) >+{ >+ uint64_t max_len = UINT64_MAX - ofs; >+ uint64_t effective_len; >+ >+ /* >+ * [MS-FSA] specifies this: >+ * >+ * If (((FileOffset + Length - 1) < FileOffset) && Length != 0) { >+ * return STATUS_INVALID_LOCK_RANGE >+ * } >+ * >+ * We avoid integer wrapping and calculate >+ * max and effective len instead. >+ */ >+ >+ if (len == 0) { >+ return true; >+ } >+ >+ effective_len = len - 1; >+ if (effective_len <= max_len) { >+ return true; >+ } >+ >+ return false; >+} >+ >+bool byte_range_overlap(uint64_t ofs1, >+ uint64_t len1, >+ uint64_t ofs2, >+ uint64_t len2) >+{ >+ uint64_t last1; >+ uint64_t last2; >+ bool valid; >+ >+ /* >+ * This is based on [MS-FSA] 2.1.4.10 >+ * Algorithm for Determining If a Range Access >+ * Conflicts with Byte-Range Locks >+ */ >+ >+ /* >+ * The {0, 0} range doesn't conflict with any byte-range lock >+ */ >+ if (ofs1 == 0 && len1 == 0) { >+ return false; >+ } >+ if (ofs2 == 0 && len2 == 0) { >+ return false; >+ } >+ >+ /* >+ * The caller should have checked that the ranges are >+ * valid. But currently we gracefully handle >+ * the overflow of a read/write check. >+ */ >+ valid = byte_range_valid(ofs1, len1); >+ if (valid) { >+ last1 = ofs1 + len1 - 1; >+ } else { >+ last1 = UINT64_MAX; >+ } >+ valid = byte_range_valid(ofs2, len2); >+ if (valid) { >+ last2 = ofs2 + len2 - 1; >+ } else { >+ last2 = UINT64_MAX; >+ } >+ >+ /* >+ * If one range starts after the last >+ * byte of the other range there's >+ * no conflict. >+ */ >+ if (ofs1 > last2) { >+ return false; >+ } >+ if (ofs2 > last1) { >+ return false; >+ } >+ >+ return true; >+} >+ > /**************************************************************************** > See if lck1 and lck2 overlap. > ****************************************************************************/ >@@ -103,20 +189,10 @@ static bool brl_same_context(const struct lock_context *ctx1, > static bool brl_overlap(const struct lock_struct *lck1, > const struct lock_struct *lck2) > { >- /* XXX Remove for Win7 compatibility. */ >- /* this extra check is not redundant - it copes with locks >- that go beyond the end of 64 bit file space */ >- if (lck1->size != 0 && >- lck1->start == lck2->start && >- lck1->size == lck2->size) { >- return True; >- } >- >- if (lck1->start >= (lck2->start+lck2->size) || >- lck2->start >= (lck1->start+lck1->size)) { >- return False; >- } >- return True; >+ return byte_range_overlap(lck1->start, >+ lck1->size, >+ lck2->start, >+ lck2->size); > } > > /**************************************************************************** >@@ -336,11 +412,12 @@ NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck, > files_struct *fsp = br_lck->fsp; > struct lock_struct *locks = br_lck->lock_data; > NTSTATUS status; >+ bool valid; > > SMB_ASSERT(plock->lock_type != UNLOCK_LOCK); > >- if ((plock->start + plock->size - 1 < plock->start) && >- plock->size != 0) { >+ valid = byte_range_valid(plock->start, plock->size); >+ if (!valid) { > return NT_STATUS_INVALID_LOCK_RANGE; > } > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 3a086fa0516..2487fa5d14d 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -31,6 +31,12 @@ void brl_shutdown(void); > unsigned int brl_num_locks(const struct byte_range_lock *brl); > struct files_struct *brl_fsp(struct byte_range_lock *brl); > >+bool byte_range_valid(uint64_t ofs, uint64_t len); >+bool byte_range_overlap(uint64_t ofs1, >+ uint64_t len1, >+ uint64_t ofs2, >+ uint64_t len2); >+ > NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck, > struct lock_struct *plock); > >-- >2.17.1 > > >From f73b670b4db103069aa151d3af4ed7a92ce581c3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 9 Aug 2019 00:47:39 +0200 >Subject: [PATCH 142/376] s3:locking: add share_mode_wakeup_waiters() helper > function > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit bd8884e5722cbbb7783fb4ae53e4f35b31031b01) >--- > source3/locking/proto.h | 1 + > source3/locking/share_mode_lock.c | 12 ++++++++++++ > 2 files changed, 13 insertions(+) > >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 2487fa5d14d..7cb8bf3e3c9 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -138,6 +138,7 @@ NTSTATUS share_mode_do_locked( > bool *modified_dependent, > void *private_data), > void *private_data); >+NTSTATUS share_mode_wakeup_waiters(struct file_id id); > > struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, > struct file_id id); >diff --git a/source3/locking/share_mode_lock.c b/source3/locking/share_mode_lock.c >index 430d14fab4a..372e188c1c0 100644 >--- a/source3/locking/share_mode_lock.c >+++ b/source3/locking/share_mode_lock.c >@@ -771,6 +771,18 @@ NTSTATUS share_mode_do_locked( > return NT_STATUS_OK; > } > >+static void share_mode_wakeup_waiters_fn(struct db_record *rec, >+ bool *modified_dependent, >+ void *private_data) >+{ >+ *modified_dependent = true; >+} >+ >+NTSTATUS share_mode_wakeup_waiters(struct file_id id) >+{ >+ return share_mode_do_locked(id, share_mode_wakeup_waiters_fn, NULL); >+} >+ > struct fetch_share_mode_unlocked_state { > TALLOC_CTX *mem_ctx; > struct share_mode_lock *lck; >-- >2.17.1 > > >From 75e07d485944fdc76a6510bf5d450959475e7e5b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 19:19:07 +0200 >Subject: [PATCH 143/376] s3:blocking: remove unused timeval_brl_min() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 3b788d97f9995e24e4005567f90a925957fb1e00) >--- > source3/smbd/blocking.c | 16 ---------------- > source3/smbd/proto.h | 2 -- > 2 files changed, 18 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index ca8a625ba9d..cdc4613270e 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -28,22 +28,6 @@ > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_LOCKING > >-/**************************************************************************** >- We need a version of timeval_min that treats zero timval as infinite. >-****************************************************************************/ >- >-struct timeval timeval_brl_min(const struct timeval *tv1, >- const struct timeval *tv2) >-{ >- if (timeval_is_zero(tv1)) { >- return *tv2; >- } >- if (timeval_is_zero(tv2)) { >- return *tv1; >- } >- return timeval_min(tv1, tv2); >-} >- > NTSTATUS smbd_do_locks_try( > struct files_struct *fsp, > enum brl_flavour lock_flav, >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index 37eeb9f31ca..b59f1f4123d 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -95,8 +95,6 @@ bool aio_add_req_to_fsp(files_struct *fsp, struct tevent_req *req); > > /* The following definitions come from smbd/blocking.c */ > >-struct timeval timeval_brl_min(const struct timeval *tv1, >- const struct timeval *tv2); > NTSTATUS smbd_do_locks_try( > struct files_struct *fsp, > enum brl_flavour lock_flav, >-- >2.17.1 > > >From 0742879bd8d03333b8b7c2a790afebdb5f7dd92b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 16:10:58 +0200 >Subject: [PATCH 144/376] s3:torture: fix the timeout alarm handling on LOCK9 > >smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK) >means existing requests are not finished with an error, >but instead just keep dangling arround. > >Pass NT_STATUS_LOCAL_DISCONNECT in order to fail the >cli_lock32() call after getting SIGALARM. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit e18c8ced8e7a872deb118191595425ef6b826bfa) >--- > source3/torture/torture.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index f26c634b7a7..5a75796928a 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -2543,7 +2543,7 @@ static void alarm_handler(int dummy) > > static void alarm_handler_parent(int dummy) > { >- smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK); >+ smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT); > } > > static void do_local_lock(int read_fd, int write_fd) >-- >2.17.1 > > >From ffdb166e49fa1a786ac1ea4e1ab09c286e75af69 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 14:31:54 +0200 >Subject: [PATCH 145/376] s3:torture: convert LOCK9 into LOCK9A and LOCK9B > >LOCK9A is the original test (with a timeout of -1) >and LOCK9B is the same but with timeout of 10 seconds. > >LOCK9B is needed to demonstrate a server bug in the next >commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit ac28eec3e4af710feab3be3d4b25bfbe38294431) >--- > selftest/skip | 2 +- > source3/selftest/tests.py | 3 ++- > source3/torture/torture.c | 38 ++++++++++++++++++++++++++------------ > 3 files changed, 29 insertions(+), 14 deletions(-) > >diff --git a/selftest/skip b/selftest/skip >index 1e7448acb9f..c471072e88f 100644 >--- a/selftest/skip >+++ b/selftest/skip >@@ -34,7 +34,7 @@ > ^samba3.smbtorture_s3.*.pipe_number > ^samba3.smbtorture_s3.LOCAL-DBTRANS #hangs for some reason > ^samba3.smbtorture_s3.*.DIR1 #loops on 64 bit linux with ext4 >-^samba3.smbtorture_s3.plain.LOCK9\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server >+^samba3.smbtorture_s3.plain.LOCK9.*\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server > ^samba3.smbtorture_s3.plain.OPLOCK2\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server > ^samba3.smbtorture_s3.plain.STREAMERROR\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server > ^samba3.smbtorture_s3.plain.DIR1\(ad_dc_ntvfs\) # Fails against the s4 ntvfs server >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index 9569aa9ae00..a3daeacae6b 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -78,7 +78,8 @@ plantestsuite("samba3.local_s3", "nt4_dc:local", [os.path.join(samba3srcdir, "sc > > plantestsuite("samba3.blackbox.registry.upgrade", "nt4_dc:local", [os.path.join(samba3srcdir, "script/tests/test_registry_upgrade.sh"), net, dbwrap_tool]) > >-tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7", "LOCK9", >+tests = ["FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", "LOCK5", "LOCK6", "LOCK7", >+ "LOCK9A", "LOCK9B", > "LOCK10", > "LOCK11", > "LOCK12", >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index 5a75796928a..66dc0cf4d1c 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -2546,7 +2546,7 @@ static void alarm_handler_parent(int dummy) > smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_LOCAL_DISCONNECT); > } > >-static void do_local_lock(int read_fd, int write_fd) >+static void do_local_lock(const char *fname, int read_fd, int write_fd) > { > int fd; > char c = '\0'; >@@ -2555,7 +2555,7 @@ static void do_local_lock(int read_fd, int write_fd) > int ret; > > local_pathname = talloc_asprintf(talloc_tos(), >- "%s/lockt9.lck", local_path); >+ "%s/%s", local_path, fname); > if (!local_pathname) { > printf("child: alloc fail\n"); > exit(1); >@@ -2614,10 +2614,10 @@ static void do_local_lock(int read_fd, int write_fd) > exit(0); > } > >-static bool run_locktest9(int dummy) >+static bool _run_locktest9X(const char *fname, int timeout) > { > struct cli_state *cli1; >- const char *fname = "\\lockt9.lck"; >+ char *fpath = talloc_asprintf(talloc_tos(), "\\%s", fname); > uint16_t fnum; > bool correct = False; > int pipe_in[2], pipe_out[2]; >@@ -2628,10 +2628,10 @@ static bool run_locktest9(int dummy) > double seconds; > NTSTATUS status; > >- printf("starting locktest9\n"); >+ printf("starting locktest9X: %s\n", fname); > > if (local_path == NULL) { >- d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n"); >+ d_fprintf(stderr, "locktest9X must be given a local path via -l <localpath>\n"); > return false; > } > >@@ -2646,7 +2646,7 @@ static bool run_locktest9(int dummy) > > if (child_pid == 0) { > /* Child. */ >- do_local_lock(pipe_out[0], pipe_in[1]); >+ do_local_lock(fname, pipe_out[0], pipe_in[1]); > exit(0); > } > >@@ -2669,7 +2669,7 @@ static bool run_locktest9(int dummy) > > smbXcli_conn_set_sockopt(cli1->conn, sockops); > >- status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, >+ status = cli_openx(cli1, fpath, O_RDWR, DENY_NONE, > &fnum); > if (!NT_STATUS_IS_OK(status)) { > d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status)); >@@ -2700,7 +2700,7 @@ static bool run_locktest9(int dummy) > > start = timeval_current(); > >- status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK); >+ status = cli_lock32(cli1, fnum, 0, 4, timeout, WRITE_LOCK); > if (!NT_STATUS_IS_OK(status)) { > d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was " > "%s\n", nt_errstr(status)); >@@ -2727,10 +2727,20 @@ fail: > > fail_nofd: > >- printf("finished locktest9\n"); >+ printf("finished locktest9X: %s\n", fname); > return correct; > } > >+static bool run_locktest9a(int dummy) >+{ >+ return _run_locktest9X("lock9a.dat", -1); >+} >+ >+static bool run_locktest9b(int dummy) >+{ >+ return _run_locktest9X("lock9b.dat", 10000); >+} >+ > struct locktest10_state { > bool ok; > bool done; >@@ -13651,8 +13661,12 @@ static struct { > .fn = run_locktest8, > }, > { >- .name = "LOCK9", >- .fn = run_locktest9, >+ .name = "LOCK9A", >+ .fn = run_locktest9a, >+ }, >+ { >+ .name = "LOCK9B", >+ .fn = run_locktest9b, > }, > { > .name = "LOCK10", >-- >2.17.1 > > >From 841fceae68098160627066dd6bd180948c048d96 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 11:09:47 +0200 >Subject: [PATCH 146/376] s3:blocking: demonstrate the posix lock retry fails > >This is just a temporary commit that shows the bug and its >fix. It will be reverted once the problem is fixed. > >The posix lock retry fails if the client specified timeout >is smaller than the hardcoded 1 second retry. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 2ec9e93a7aac2706b4a5931495d56a7b64f8d894) >--- > selftest/knownfail.d/lock9 | 1 + > source3/smbd/blocking.c | 4 ++-- > 2 files changed, 3 insertions(+), 2 deletions(-) > create mode 100644 selftest/knownfail.d/lock9 > >diff --git a/selftest/knownfail.d/lock9 b/selftest/knownfail.d/lock9 >new file mode 100644 >index 00000000000..044622586eb >--- /dev/null >+++ b/selftest/knownfail.d/lock9 >@@ -0,0 +1 @@ >+^samba3.smbtorture_s3.*.LOCK9B >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index cdc4613270e..91438fe4486 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -236,7 +236,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > > DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); > >- tmp = timeval_current_ofs(1, 0); >+ tmp = timeval_current_ofs(15, 0); > endtime = timeval_min(&endtime, &tmp); > } > >@@ -381,7 +381,7 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) > > DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); > >- tmp = timeval_current_ofs(1, 0); >+ tmp = timeval_current_ofs(15, 0); > endtime = timeval_min(&endtime, &tmp); > } > >-- >2.17.1 > > >From b381f4b314c71c446a847de7cdb5baa658455c90 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 18:34:36 +0200 >Subject: [PATCH 147/376] s3:blocking: split smbd_smb1_do_locks_retry() into > _try() and _retry() > >This will make it possible to have just one caller to >smbd_do_locks_try() later and use smbd_smb1_do_locks_try() >from within smbd_smb1_do_locks_send(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Reviewed-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit e79fcfaaf2ecfca6c3747f6fe4be51f332ebf10d) >--- > source3/smbd/blocking.c | 72 ++++++++++++++++++++++++----------------- > 1 file changed, 42 insertions(+), 30 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 91438fe4486..0fa39ae58ab 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -109,6 +109,7 @@ struct smbd_smb1_do_locks_state { > uint16_t blocker; > }; > >+static void smbd_smb1_do_locks_try(struct tevent_req *req); > static void smbd_smb1_do_locks_retry(struct tevent_req *subreq); > static void smbd_smb1_blocked_locks_cleanup( > struct tevent_req *req, enum tevent_req_state req_state); >@@ -300,10 +301,8 @@ static void smbd_smb1_blocked_locks_cleanup( > fsp, blocked, struct tevent_req *, num_blocked-1); > } > >-static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) >+static void smbd_smb1_do_locks_try(struct tevent_req *req) > { >- struct tevent_req *req = tevent_req_callback_data( >- subreq, struct tevent_req); > struct smbd_smb1_do_locks_state *state = tevent_req_data( > req, struct smbd_smb1_do_locks_state); > struct files_struct *fsp = state->fsp; >@@ -315,36 +314,10 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) > struct timeval endtime; > struct server_id blocking_pid = { 0 }; > uint64_t blocking_smblctx = 0; >+ struct tevent_req *subreq = NULL; > NTSTATUS status; > bool ok; > >- /* >- * Make sure we run as the user again >- */ >- ok = change_to_user_by_fsp(state->fsp); >- if (!ok) { >- tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >- return; >- } >- >- status = dbwrap_watched_watch_recv(subreq, NULL, NULL); >- TALLOC_FREE(subreq); >- >- DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n", >- nt_errstr(status)); >- >- if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >- double elapsed = timeval_elapsed(&state->endtime); >- if (elapsed > 0) { >- smbd_smb1_brl_finish_by_req( >- req, NT_STATUS_FILE_LOCK_CONFLICT); >- return; >- } >- /* >- * This is a posix lock retry. Just retry. >- */ >- } >- > lck = get_existing_share_mode_lock(state, fsp->file_id); > if (tevent_req_nomem(lck, req)) { > DBG_DEBUG("Could not get share mode lock\n"); >@@ -396,6 +369,45 @@ done: > smbd_smb1_brl_finish_by_req(req, status); > } > >+static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct smbd_smb1_do_locks_state *state = tevent_req_data( >+ req, struct smbd_smb1_do_locks_state); >+ NTSTATUS status; >+ bool ok; >+ >+ /* >+ * Make sure we run as the user again >+ */ >+ ok = change_to_user_by_fsp(state->fsp); >+ if (!ok) { >+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >+ return; >+ } >+ >+ status = dbwrap_watched_watch_recv(subreq, NULL, NULL); >+ TALLOC_FREE(subreq); >+ >+ DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n", >+ nt_errstr(status)); >+ >+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >+ double elapsed = timeval_elapsed(&state->endtime); >+ if (elapsed > 0) { >+ smbd_smb1_brl_finish_by_req( >+ req, NT_STATUS_FILE_LOCK_CONFLICT); >+ return; >+ } >+ /* >+ * This is a posix lock retry. Just retry. >+ */ >+ } >+ >+ smbd_smb1_do_locks_try(req); >+} >+ > NTSTATUS smbd_smb1_do_locks_recv(struct tevent_req *req) > { > struct smbd_smb1_do_locks_state *state = tevent_req_data( >-- >2.17.1 > > >From 6b23f24ee383763c45af8c627df09060d76d9dd8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 18:34:36 +0200 >Subject: [PATCH 148/376] s3:blocking: move from 'timeout' to > 'smbd_smb1_do_locks_state->timeout' > >This will make it possible to just use smbd_smb1_do_locks_try() >in a later commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8fe708acb43ea36d0cbf398713b125daba180a2d) >--- > source3/smbd/blocking.c | 20 +++++++++++--------- > source3/smbd/proto.h | 2 +- > 2 files changed, 12 insertions(+), 10 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 0fa39ae58ab..81facc43154 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -101,6 +101,7 @@ struct smbd_smb1_do_locks_state { > struct tevent_context *ev; > struct smb_request *smbreq; > struct files_struct *fsp; >+ uint32_t timeout; > struct timeval endtime; > bool large_offset; /* required for correct cancel */ > enum brl_flavour lock_flav; >@@ -119,7 +120,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > struct tevent_context *ev, > struct smb_request **smbreq, /* talloc_move()d into our state */ > struct files_struct *fsp, >- uint32_t timeout, >+ uint32_t lock_timeout, > bool large_offset, > enum brl_flavour lock_flav, > uint16_t num_locks, >@@ -142,6 +143,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > state->ev = ev; > state->smbreq = talloc_move(state, smbreq); > state->fsp = fsp; >+ state->timeout = lock_timeout; > state->large_offset = large_offset; > state->lock_flav = lock_flav; > state->num_locks = num_locks; >@@ -155,13 +157,13 @@ struct tevent_req *smbd_smb1_do_locks_send( > return tevent_req_post(req, ev); > } > >- if ((timeout != 0) && (timeout != UINT32_MAX)) { >+ if ((state->timeout != 0) && (state->timeout != UINT32_MAX)) { > /* > * Windows internal resolution for blocking locks > * seems to be about 200ms... Don't wait for less than > * that. JRA. > */ >- timeout = MAX(timeout, lp_lock_spin_time()); >+ state->timeout = MAX(state->timeout, lp_lock_spin_time()); > } > > lck = get_existing_share_mode_lock(state, state->fsp->file_id); >@@ -187,7 +189,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > goto done; > } > >- if (timeout == 0) { >+ if (state->timeout == 0) { > struct smbd_lock_element *blocker = &locks[state->blocker]; > > if ((blocker->offset >= 0xEF000000) && >@@ -196,7 +198,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > * This must be an optimization of an ancient > * application bug... > */ >- timeout = lp_lock_spin_time(); >+ state->timeout = lp_lock_spin_time(); > } > > if ((fsp->lock_failure_seen) && >@@ -208,15 +210,15 @@ struct tevent_req *smbd_smb1_do_locks_send( > */ > DBG_DEBUG("Delaying lock request due to previous " > "failure\n"); >- timeout = lp_lock_spin_time(); >+ state->timeout = lp_lock_spin_time(); > } > } > > DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", >- timeout, >+ state->timeout, > blocking_smblctx); > >- if (timeout == 0) { >+ if (state->timeout == 0) { > tevent_req_nterror(req, status); > goto done; > } >@@ -229,7 +231,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > TALLOC_FREE(lck); > tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); > >- state->endtime = timeval_current_ofs_msec(timeout); >+ state->endtime = timeval_current_ofs_msec(state->timeout); > endtime = state->endtime; > > if (blocking_smblctx == UINT64_MAX) { >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index b59f1f4123d..cd1ec9a1f9e 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -108,7 +108,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > struct tevent_context *ev, > struct smb_request **smbreq, /* talloc_move()d into our state */ > struct files_struct *fsp, >- uint32_t timeout, >+ uint32_t lock_timeout, > bool large_offset, > enum brl_flavour lock_flav, > uint16_t num_locks, >-- >2.17.1 > > >From 2c31c9d365d3aaa323e10abff15fc4404a4a52dd Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 14:21:38 +0200 >Subject: [PATCH 149/376] s3:blocking: fix posix lock retry > >We should evaluate the timeout condition after the very last >retry and not before. > >Otherwise we'd fail to retry when waiting for posix locks. >The problem happens if the client provided timeout is smaller >than the 1 sec (for testing temporary 15 secs) retry. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit e8d719d31f885d7b6d5b317165f90ec40df169c9) >--- > selftest/knownfail.d/lock9 | 1 - > source3/smbd/blocking.c | 36 +++++++++++++++++++++++++----------- > 2 files changed, 25 insertions(+), 12 deletions(-) > delete mode 100644 selftest/knownfail.d/lock9 > >diff --git a/selftest/knownfail.d/lock9 b/selftest/knownfail.d/lock9 >deleted file mode 100644 >index 044622586eb..00000000000 >--- a/selftest/knownfail.d/lock9 >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smbtorture_s3.*.LOCK9B >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 81facc43154..587923aa5ec 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -319,6 +319,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > struct tevent_req *subreq = NULL; > NTSTATUS status; > bool ok; >+ double elapsed; > > lck = get_existing_share_mode_lock(state, fsp->file_id); > if (tevent_req_nomem(lck, req)) { >@@ -341,6 +342,24 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > goto done; > } > >+ /* >+ * The client specified timeout elapsed >+ * avoid further retries. >+ * >+ * Otherwise keep waiting either waiting >+ * for changes in locking.tdb or the polling >+ * mode timers waiting for posix locks. >+ */ >+ elapsed = timeval_elapsed(&state->endtime); >+ if (elapsed > 0) { >+ /* >+ * On timeout we always return >+ * NT_STATUS_FILE_LOCK_CONFLICT >+ */ >+ status = NT_STATUS_FILE_LOCK_CONFLICT; >+ goto done; >+ } >+ > subreq = dbwrap_watched_watch_send( > state, state->ev, lck->data->record, blocking_pid); > if (tevent_req_nomem(subreq, req)) { >@@ -395,17 +414,12 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) > DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n", > nt_errstr(status)); > >- if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >- double elapsed = timeval_elapsed(&state->endtime); >- if (elapsed > 0) { >- smbd_smb1_brl_finish_by_req( >- req, NT_STATUS_FILE_LOCK_CONFLICT); >- return; >- } >- /* >- * This is a posix lock retry. Just retry. >- */ >- } >+ /* >+ * We ignore any errors here, it's most likely >+ * we just get NT_STATUS_OK or NT_STATUS_IO_TIMEOUT. >+ * >+ * In any case we can just give it a retry. >+ */ > > smbd_smb1_do_locks_try(req); > } >-- >2.17.1 > > >From e91bae2bdb11c8466a42ae51660bb564de1aedc2 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 16:44:11 +0200 >Subject: [PATCH 150/376] s3:blocking: Remove bug reproducer from a few commits > ago > >The problem is fixed, now we can revert the change that made it >easier to trigger. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 62ec58b06c38ee82bb3147c4d325413fd3a76499) >--- > source3/smbd/blocking.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 587923aa5ec..af889a10d62 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -239,7 +239,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > > DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); > >- tmp = timeval_current_ofs(15, 0); >+ tmp = timeval_current_ofs(1, 0); > endtime = timeval_min(&endtime, &tmp); > } > >@@ -375,7 +375,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > > DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); > >- tmp = timeval_current_ofs(15, 0); >+ tmp = timeval_current_ofs(1, 0); > endtime = timeval_min(&endtime, &tmp); > } > >-- >2.17.1 > > >From 1fd0a52e6727b191aa008f7a260ad748d34d5870 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 17:26:43 +0200 >Subject: [PATCH 151/376] s3:blocking: use dynamic posix lock wait intervals > >We want to start with a short timeout (200ms) and >slow down to larger timeouts up to 2s for the default >value of "lock spin time". > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 15765644d2590d6549f8fcc01c39c56387eed654) >--- > source3/smbd/blocking.c | 41 +++++++++++++++++++++++++++++++++++++---- > 1 file changed, 37 insertions(+), 4 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index af889a10d62..50e1d436eb7 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -102,6 +102,7 @@ struct smbd_smb1_do_locks_state { > struct smb_request *smbreq; > struct files_struct *fsp; > uint32_t timeout; >+ uint32_t polling_msecs; > struct timeval endtime; > bool large_offset; /* required for correct cancel */ > enum brl_flavour lock_flav; >@@ -115,6 +116,32 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq); > static void smbd_smb1_blocked_locks_cleanup( > struct tevent_req *req, enum tevent_req_state req_state); > >+static void smbd_smb1_do_locks_update_polling_msecs( >+ struct smbd_smb1_do_locks_state *state) >+{ >+ /* >+ * The default lp_lock_spin_time() is 200ms. >+ * >+ * v_min is in the range of 0.002 to 20 secs >+ * (0.2 secs by default) >+ * >+ * v_max is in the range of 0.02 to 200 secs >+ * (2.0 secs by default) >+ * >+ * The typical steps are: >+ * 0.2, 0.4, 0.6, 0.8, ... 2.0 >+ */ >+ uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time())); >+ uint32_t v_max = 10 * v_min; >+ >+ if (state->polling_msecs >= v_max) { >+ state->polling_msecs = v_max; >+ return; >+ } >+ >+ state->polling_msecs += v_min; >+} >+ > struct tevent_req *smbd_smb1_do_locks_send( > TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >@@ -237,9 +264,12 @@ struct tevent_req *smbd_smb1_do_locks_send( > if (blocking_smblctx == UINT64_MAX) { > struct timeval tmp; > >- DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); >+ smbd_smb1_do_locks_update_polling_msecs(state); >+ >+ DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", >+ state->polling_msecs); > >- tmp = timeval_current_ofs(1, 0); >+ tmp = timeval_current_ofs_msec(state->polling_msecs); > endtime = timeval_min(&endtime, &tmp); > } > >@@ -373,9 +403,12 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > if (blocking_smblctx == UINT64_MAX) { > struct timeval tmp; > >- DBG_DEBUG("Blocked on a posix lock. Retry in one second\n"); >+ smbd_smb1_do_locks_update_polling_msecs(state); >+ >+ DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", >+ state->polling_msecs); > >- tmp = timeval_current_ofs(1, 0); >+ tmp = timeval_current_ofs_msec(state->polling_msecs); > endtime = timeval_min(&endtime, &tmp); > } > >-- >2.17.1 > > >From 85b9b5f04fdf7fa432f7260b27f77342f27dddbb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 16:30:16 +0200 >Subject: [PATCH 152/376] s4:torture/raw: assert to get LOCK_NOT_GRANTED in > torture_samba3_posixtimedlock() > >There should not be a different if the blocker is a posix process >instead of another smbd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 2a77025a1e16d897281e5840192c93fa03328681) >--- > selftest/knownfail.d/samba3posixtimedlock | 1 + > source4/torture/raw/samba3misc.c | 6 +++--- > 2 files changed, 4 insertions(+), 3 deletions(-) > create mode 100644 selftest/knownfail.d/samba3posixtimedlock > >diff --git a/selftest/knownfail.d/samba3posixtimedlock b/selftest/knownfail.d/samba3posixtimedlock >new file mode 100644 >index 00000000000..56d2d349e1e >--- /dev/null >+++ b/selftest/knownfail.d/samba3posixtimedlock >@@ -0,0 +1 @@ >+^samba3.raw.samba3posixtimedlock.samba3posixtimedlock >diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c >index dc460b9cd8b..2f484023bea 100644 >--- a/source4/torture/raw/samba3misc.c >+++ b/source4/torture/raw/samba3misc.c >@@ -775,8 +775,8 @@ static void receive_lock_result(struct smbcli_request *req) > } > > /* >- * Check that Samba3 correctly deals with conflicting posix byte range locks >- * on an underlying file >+ * Check that Samba3 correctly deals with conflicting local posix byte range >+ * locks on an underlying file via "normal" SMB1 (without unix extentions). > * > * Note: This test depends on "posix locking = yes". > * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>" >@@ -873,7 +873,7 @@ bool torture_samba3_posixtimedlock(struct torture_context *tctx, struct smbcli_s > status = smb_raw_lock(cli->tree, &io); > > ret = true; >- CHECK_STATUS(tctx, status, NT_STATUS_FILE_LOCK_CONFLICT); >+ CHECK_STATUS(tctx, status, NT_STATUS_LOCK_NOT_GRANTED); > > if (!ret) { > goto done; >-- >2.17.1 > > >From b56bb2ac59dd190cdf3c726a7becf2ae9d296657 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 12:04:43 +0200 >Subject: [PATCH 153/376] s3:blocking: maintain state->deny_status > >For Windows locks we start with LOCK_NOT_GRANTED and use >FILE_LOCK_CONFLICT if we retried after a timeout. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit aba0ee46258f3dd910421facb742fce3318a6946) >--- > selftest/knownfail.d/samba3posixtimedlock | 1 - > source3/smbd/blocking.c | 33 +++++++++++++++++++---- > 2 files changed, 28 insertions(+), 6 deletions(-) > delete mode 100644 selftest/knownfail.d/samba3posixtimedlock > >diff --git a/selftest/knownfail.d/samba3posixtimedlock b/selftest/knownfail.d/samba3posixtimedlock >deleted file mode 100644 >index 56d2d349e1e..00000000000 >--- a/selftest/knownfail.d/samba3posixtimedlock >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.raw.samba3posixtimedlock.samba3posixtimedlock >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 50e1d436eb7..a87d62d910a 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -109,6 +109,7 @@ struct smbd_smb1_do_locks_state { > uint16_t num_locks; > struct smbd_lock_element *locks; > uint16_t blocker; >+ NTSTATUS deny_status; > }; > > static void smbd_smb1_do_locks_try(struct tevent_req *req); >@@ -176,6 +177,16 @@ struct tevent_req *smbd_smb1_do_locks_send( > state->num_locks = num_locks; > state->locks = locks; > >+ if (lock_flav == POSIX_LOCK) { >+ /* >+ * SMB1 posix locks always use >+ * NT_STATUS_FILE_LOCK_CONFLICT. >+ */ >+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; >+ } else { >+ state->deny_status = NT_STATUS_LOCK_NOT_GRANTED; >+ } >+ > DBG_DEBUG("state=%p, state->smbreq=%p\n", state, state->smbreq); > > if (num_locks == 0) { >@@ -245,10 +256,19 @@ struct tevent_req *smbd_smb1_do_locks_send( > state->timeout, > blocking_smblctx); > >+ /* >+ * If the endtime is not elapsed yet, >+ * it means we'll retry after a timeout. >+ * In that case we'll have to return >+ * NT_STATUS_FILE_LOCK_CONFLICT >+ * instead of NT_STATUS_LOCK_NOT_GRANTED. >+ */ > if (state->timeout == 0) { >+ status = state->deny_status; > tevent_req_nterror(req, status); > goto done; > } >+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; > > subreq = dbwrap_watched_watch_send( > state, state->ev, lck->data->record, blocking_pid); >@@ -379,16 +399,19 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > * Otherwise keep waiting either waiting > * for changes in locking.tdb or the polling > * mode timers waiting for posix locks. >+ * >+ * If the endtime is not expired yet, >+ * it means we'll retry after a timeout. >+ * In that case we'll have to return >+ * NT_STATUS_FILE_LOCK_CONFLICT >+ * instead of NT_STATUS_LOCK_NOT_GRANTED. > */ > elapsed = timeval_elapsed(&state->endtime); > if (elapsed > 0) { >- /* >- * On timeout we always return >- * NT_STATUS_FILE_LOCK_CONFLICT >- */ >- status = NT_STATUS_FILE_LOCK_CONFLICT; >+ status = state->deny_status; > goto done; > } >+ state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; > > subreq = dbwrap_watched_watch_send( > state, state->ev, lck->data->record, blocking_pid); >-- >2.17.1 > > >From 8b3a50609f430ec08add2bbac77b106a585d97c6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 12:33:28 +0200 >Subject: [PATCH 154/376] s3:brlock: always return LOCK_NOT_GRANTED instead of > FILE_LOCK_CONFLICT > >Returning NT_STATUS_FILE_LOCK_CONFLICT is a SMB1 only detail >for delayed brlock requests, which is handled in >smbd_smb1_do_locks*(). > >The brlock layer should be consistent even for posix locks. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Signed-off-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit ad98eec6090430ba5296a5111dde2e53b9cd217a) >--- > source3/locking/brlock.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c >index 628c2574357..0a85bd0b057 100644 >--- a/source3/locking/brlock.c >+++ b/source3/locking/brlock.c >@@ -462,7 +462,7 @@ NTSTATUS brl_lock_windows_default(struct byte_range_lock *br_lck, > plock->context.smblctx = 0xFFFFFFFFFFFFFFFFLL; > > if (errno_ret == EACCES || errno_ret == EAGAIN) { >- status = NT_STATUS_FILE_LOCK_CONFLICT; >+ status = NT_STATUS_LOCK_NOT_GRANTED; > goto fail; > } else { > status = map_nt_error_from_unix(errno); >@@ -829,7 +829,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, > TALLOC_FREE(tp); > /* Remember who blocked us. */ > plock->context.smblctx = curr_lock->context.smblctx; >- return NT_STATUS_FILE_LOCK_CONFLICT; >+ return NT_STATUS_LOCK_NOT_GRANTED; > } > /* Just copy the Windows lock into the new array. */ > memcpy(&tp[count], curr_lock, sizeof(struct lock_struct)); >@@ -849,7 +849,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, > TALLOC_FREE(tp); > /* Remember who blocked us. */ > plock->context.smblctx = curr_lock->context.smblctx; >- return NT_STATUS_FILE_LOCK_CONFLICT; >+ return NT_STATUS_LOCK_NOT_GRANTED; > } > > /* Work out overlaps. */ >@@ -912,7 +912,7 @@ static NTSTATUS brl_lock_posix(struct byte_range_lock *br_lck, > > if (errno_ret == EACCES || errno_ret == EAGAIN) { > TALLOC_FREE(tp); >- status = NT_STATUS_FILE_LOCK_CONFLICT; >+ status = NT_STATUS_LOCK_NOT_GRANTED; > goto fail; > } else { > TALLOC_FREE(tp); >-- >2.17.1 > > >From e5385142987202a67fc3667506ee233f2c726107 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 16:14:23 +0200 >Subject: [PATCH 155/376] s3:smb2_lock: move from 'blocking' to > 'state->blocking' > >This will simplify the next commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit f13d13ae9da3072862a781bc926e7a06e8384337) >--- > source3/smbd/smb2_lock.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index e9c8d7f890e..4cf735ff48d 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -42,6 +42,7 @@ struct smbd_smb2_lock_state { > struct smbd_smb2_request *smb2req; > struct smb_request *smb1req; > struct files_struct *fsp; >+ bool blocking; > uint16_t lock_count; > struct smbd_lock_element *locks; > }; >@@ -200,7 +201,6 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > { > struct tevent_req *req; > struct smbd_smb2_lock_state *state; >- bool blocking = false; > bool isunlock = false; > uint16_t i; > struct smbd_lock_element *locks; >@@ -241,7 +241,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); > return tevent_req_post(req, ev); > } >- blocking = true; >+ state->blocking = true; > break; > > case SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_FAIL_IMMEDIATELY: >@@ -383,7 +383,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (blocking && >+ if (state->blocking && > (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) || > NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT))) { > struct tevent_req *subreq; >-- >2.17.1 > > >From 5e156be97a37b9bd42b18a78cf6ab541271971e7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 16:39:41 +0200 >Subject: [PATCH 156/376] s3:smb2_lock: split smbd_smb2_lock_retry() into > _try() and _retry() > >This makes it possible to reuse _try() in the _send() function in the >next commits. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit d096742da1a045357f52ccd5b28d499c30e96152) >--- > source3/smbd/smb2_lock.c | 49 ++++++++++++++++++++++++---------------- > 1 file changed, 30 insertions(+), 19 deletions(-) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 4cf735ff48d..c2b4603f3e1 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -189,6 +189,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq) > } > } > >+static void smbd_smb2_lock_try(struct tevent_req *req); > static void smbd_smb2_lock_retry(struct tevent_req *subreq); > static bool smbd_smb2_lock_cancel(struct tevent_req *req); > >@@ -410,10 +411,8 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >-static void smbd_smb2_lock_retry(struct tevent_req *subreq) >+static void smbd_smb2_lock_try(struct tevent_req *req) > { >- struct tevent_req *req = tevent_req_callback_data( >- subreq, struct tevent_req); > struct smbd_smb2_lock_state *state = tevent_req_data( > req, struct smbd_smb2_lock_state); > struct share_mode_lock *lck = NULL; >@@ -421,22 +420,7 @@ static void smbd_smb2_lock_retry(struct tevent_req *subreq) > struct server_id blocking_pid = { 0 }; > uint64_t blocking_smblctx; > NTSTATUS status; >- bool ok; >- >- /* >- * Make sure we run as the user again >- */ >- ok = change_to_user_by_fsp(state->fsp); >- if (!ok) { >- tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >- return; >- } >- >- status = dbwrap_watched_watch_recv(subreq, NULL, NULL); >- TALLOC_FREE(subreq); >- if (tevent_req_nterror(req, status)) { >- return; >- } >+ struct tevent_req *subreq = NULL; > > lck = get_existing_share_mode_lock( > talloc_tos(), state->fsp->file_id); >@@ -467,6 +451,33 @@ static void smbd_smb2_lock_retry(struct tevent_req *subreq) > tevent_req_set_callback(subreq, smbd_smb2_lock_retry, req); > } > >+static void smbd_smb2_lock_retry(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct smbd_smb2_lock_state *state = tevent_req_data( >+ req, struct smbd_smb2_lock_state); >+ NTSTATUS status; >+ bool ok; >+ >+ /* >+ * Make sure we run as the user again >+ */ >+ ok = change_to_user_by_fsp(state->fsp); >+ if (!ok) { >+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED); >+ return; >+ } >+ >+ status = dbwrap_watched_watch_recv(subreq, NULL, NULL); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ >+ smbd_smb2_lock_try(req); >+} >+ > static NTSTATUS smbd_smb2_lock_recv(struct tevent_req *req) > { > return tevent_req_simple_recv_ntstatus(req); >-- >2.17.1 > > >From c4ab0c8502284ee0a4e4336f42c352b5a19dda43 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 16:39:41 +0200 >Subject: [PATCH 157/376] s3:smb2_lock: error out early in > smbd_smb2_lock_send() > >We no longer expect NT_STATUS_FILE_LOCK_CONFLICT from >the VFS layer and assert that in a future version. > >This makes it easier to port the same logic to smbd_smb2_lock_try(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 39d514cdc358f175d0968f4a78f8f2f05a6c1707) >--- > source3/smbd/smb2_lock.c | 22 +++++++++++++++++++--- > 1 file changed, 19 insertions(+), 3 deletions(-) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index c2b4603f3e1..c049c33ebbc 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -383,10 +383,26 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > tevent_req_done(req); > return tevent_req_post(req, ev); > } >+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { >+ /* >+ * This is a bug and will be changed into an assert >+ * in a future version. We should only >+ * ever get NT_STATUS_LOCK_NOT_GRANTED here! >+ */ >+ static uint64_t _bug_count; >+ int _level = (_bug_count++ == 0) ? DBGLVL_ERR: DBGLVL_DEBUG; >+ DBG_PREFIX(_level, ("BUG: Got %s mapping to " >+ "NT_STATUS_LOCK_NOT_GRANTED\n", >+ nt_errstr(status))); >+ status = NT_STATUS_LOCK_NOT_GRANTED; >+ } >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) { >+ TALLOC_FREE(lck); >+ tevent_req_nterror(req, status); >+ return tevent_req_post(req, ev); >+ } > >- if (state->blocking && >- (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED) || >- NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT))) { >+ if (state->blocking) { > struct tevent_req *subreq; > > DBG_DEBUG("Watching share mode lock\n"); >-- >2.17.1 > > >From 1fb82e04d0231392a9243b6b924e6c1765110a8d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 16:39:41 +0200 >Subject: [PATCH 158/376] s3:smb2_lock: let smbd_smb2_lock_try() explicitly > check for the retry condition > >This makes it possible to reuse _try() in the _send() function in the >next commit. > >We should not retry forever on a hard error. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7f77e0b4e9878f1f3515206d052adc012e26aafb) >--- > source3/smbd/smb2_lock.c | 26 ++++++++++++++++++++++++++ > 1 file changed, 26 insertions(+) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index c049c33ebbc..153705b26a1 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -457,6 +457,32 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > tevent_req_done(req); > return; > } >+ if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { >+ /* >+ * This is a bug and will be changed into an assert >+ * in future version. We should only >+ * ever get NT_STATUS_LOCK_NOT_GRANTED here! >+ */ >+ static uint64_t _bug_count; >+ int _level = (_bug_count++ == 0) ? DBGLVL_ERR: DBGLVL_DEBUG; >+ DBG_PREFIX(_level, ("BUG: Got %s mapping to " >+ "NT_STATUS_LOCK_NOT_GRANTED\n", >+ nt_errstr(status))); >+ status = NT_STATUS_LOCK_NOT_GRANTED; >+ } >+ if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) { >+ TALLOC_FREE(lck); >+ tevent_req_nterror(req, status); >+ return; >+ } >+ >+ if (!state->blocking) { >+ TALLOC_FREE(lck); >+ tevent_req_nterror(req, status); >+ return; >+ } >+ >+ DBG_DEBUG("Watching share mode lock\n"); > > subreq = dbwrap_watched_watch_send( > state, state->ev, lck->data->record, blocking_pid); >-- >2.17.1 > > >From 00fc583960f0983c84f960408c8cc92c25c0a928 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 13 Aug 2019 16:39:41 +0200 >Subject: [PATCH 159/376] s3:smb2_lock: make use of smbd_smb2_lock_try() in > smbd_smb2_lock_send() > >We only need the logic to call smbd_do_locks_try() and a possible >retry once in smbd_smb2_lock_try(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 359e9992be713bbecfdb19998d69e1d3f020c5e9) >--- > source3/smbd/smb2_lock.c | 68 ++++------------------------------------ > 1 file changed, 6 insertions(+), 62 deletions(-) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 153705b26a1..a8ccf21cc20 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -205,10 +205,6 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > bool isunlock = false; > uint16_t i; > struct smbd_lock_element *locks; >- struct share_mode_lock *lck = NULL; >- uint16_t blocker_idx; >- struct server_id blocking_pid = { 0 }; >- uint64_t blocking_smblctx; > NTSTATUS status; > > req = tevent_req_create(mem_ctx, &state, >@@ -363,68 +359,16 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- lck = get_existing_share_mode_lock( >- talloc_tos(), state->fsp->file_id); >- if (tevent_req_nomem(lck, req)) { >- return tevent_req_post(req, ev); >- } >- >- status = smbd_do_locks_try( >- state->fsp, >- WINDOWS_LOCK, >- state->lock_count, >- state->locks, >- &blocker_idx, >- &blocking_pid, >- &blocking_smblctx); >- >- if (NT_STATUS_IS_OK(status)) { >- TALLOC_FREE(lck); >- tevent_req_done(req); >- return tevent_req_post(req, ev); >- } >- if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { >- /* >- * This is a bug and will be changed into an assert >- * in a future version. We should only >- * ever get NT_STATUS_LOCK_NOT_GRANTED here! >- */ >- static uint64_t _bug_count; >- int _level = (_bug_count++ == 0) ? DBGLVL_ERR: DBGLVL_DEBUG; >- DBG_PREFIX(_level, ("BUG: Got %s mapping to " >- "NT_STATUS_LOCK_NOT_GRANTED\n", >- nt_errstr(status))); >- status = NT_STATUS_LOCK_NOT_GRANTED; >- } >- if (!NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) { >- TALLOC_FREE(lck); >- tevent_req_nterror(req, status); >+ smbd_smb2_lock_try(req); >+ if (!tevent_req_is_in_progress(req)) { > return tevent_req_post(req, ev); > } > >- if (state->blocking) { >- struct tevent_req *subreq; >- >- DBG_DEBUG("Watching share mode lock\n"); >- >- subreq = dbwrap_watched_watch_send( >- state, state->ev, lck->data->record, blocking_pid); >- TALLOC_FREE(lck); >- if (tevent_req_nomem(subreq, req)) { >- return tevent_req_post(req, ev); >- } >- tevent_req_set_callback(subreq, smbd_smb2_lock_retry, req); >- >- tevent_req_defer_callback(req, smb2req->sconn->ev_ctx); >- aio_add_req_to_fsp(state->fsp, req); >- tevent_req_set_cancel_fn(req, smbd_smb2_lock_cancel); >+ tevent_req_defer_callback(req, smb2req->sconn->ev_ctx); >+ aio_add_req_to_fsp(state->fsp, req); >+ tevent_req_set_cancel_fn(req, smbd_smb2_lock_cancel); > >- return req; >- } >- >- TALLOC_FREE(lck); >- tevent_req_nterror(req, status); >- return tevent_req_post(req, ev); >+ return req; > } > > static void smbd_smb2_lock_try(struct tevent_req *req) >-- >2.17.1 > > >From 061b60353d76ac368f7e48df9fe7fb899f7a2642 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 17:38:30 +0200 >Subject: [PATCH 160/376] s4:torture/smb2: add smb2.samba3misc.localposixlock1 > >This demonstrates that the SMB2 code path doesn't do >any retry for local posix locks. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7155d3a2c5d7237f00cccb1802c1341cf295864e) >--- > selftest/knownfail.d/smb2.localposixlock | 1 + > selftest/skip | 1 + > source3/selftest/tests.py | 2 +- > source4/torture/smb2/samba3misc.c | 188 +++++++++++++++++++++++ > source4/torture/smb2/smb2.c | 1 + > source4/torture/smb2/wscript_build | 1 + > 6 files changed, 193 insertions(+), 1 deletion(-) > create mode 100644 selftest/knownfail.d/smb2.localposixlock > create mode 100644 source4/torture/smb2/samba3misc.c > >diff --git a/selftest/knownfail.d/smb2.localposixlock b/selftest/knownfail.d/smb2.localposixlock >new file mode 100644 >index 00000000000..1b84f074e0b >--- /dev/null >+++ b/selftest/knownfail.d/smb2.localposixlock >@@ -0,0 +1 @@ >+^samba3.smb2.samba3misc.localposixlock1 >diff --git a/selftest/skip b/selftest/skip >index c471072e88f..11bf29599fa 100644 >--- a/selftest/skip >+++ b/selftest/skip >@@ -93,6 +93,7 @@ > ^samba4.rpc.samr.passwords.*ncacn_np\(ad_dc_slowtests\) # currently fails, possibly config issue > ^samba4.rpc.samr.passwords.*s4member # currently fails, possibly config issue > ^samba4.raw.scan.eamax >+^samba4.smb2.samba3misc > ^samba4.smb2.notify > ^samba4.smb2.scan > ^samba4.smb2.lease >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index a3daeacae6b..ebc366de3ea 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -529,7 +529,7 @@ for t in tests: > plansmbtorture4testsuite(t, env, '//$SERVER/tmp -k yes -U$DC_USERNAME@$REALM%$DC_PASSWORD --option=torture:addc=$DC_SERVER', description='kerberos connection') > plansmbtorture4testsuite(t, env, '//$SERVER/tmpguest -U% --option=torture:addc=$DC_SERVER', description='anonymous connection') > plansmbtorture4testsuite(t, env, '//$SERVER/tmp -k no -U$DC_USERNAME@$REALM%$DC_PASSWORD', description='ntlm user@realm') >- elif t == "raw.samba3posixtimedlock": >+ elif t == "raw.samba3posixtimedlock" or t == "smb2.samba3misc": > plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share') > plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/ad_dc/share') > elif t == "raw.chkpath": >diff --git a/source4/torture/smb2/samba3misc.c b/source4/torture/smb2/samba3misc.c >new file mode 100644 >index 00000000000..a5fe6c1bbea >--- /dev/null >+++ b/source4/torture/smb2/samba3misc.c >@@ -0,0 +1,188 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ Test some misc Samba3 code paths >+ >+ Copyright (C) Volker Lendecke 2006 >+ Copyright (C) Stefan Metzmacher 2019 >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#include "includes.h" >+#include "system/time.h" >+#include "system/filesys.h" >+#include "libcli/smb2/smb2.h" >+#include "libcli/smb2/smb2_calls.h" >+#include "../libcli/smb/smbXcli_base.h" >+#include "torture/torture.h" >+#include "torture/smb2/proto.h" >+#include "torture/util.h" >+#include "lib/events/events.h" >+#include "param/param.h" >+ >+#define CHECK_STATUS(status, correct) do { \ >+ const char *_cmt = "(" __location__ ")"; \ >+ torture_assert_ntstatus_equal_goto(tctx,status,correct, \ >+ ret,done,_cmt); \ >+ } while (0) >+ >+#define BASEDIR "samba3misc.smb2" >+ >+#define WAIT_FOR_ASYNC_RESPONSE(req) \ >+ while (!req->cancel.can_cancel && req->state <= SMB2_REQUEST_RECV) { \ >+ if (tevent_loop_once(tctx->ev) != 0) { \ >+ break; \ >+ } \ >+ } >+ >+static void torture_smb2_tree_disconnect_timer(struct tevent_context *ev, >+ struct tevent_timer *te, >+ struct timeval now, >+ void *private_data) >+{ >+ struct smb2_tree *tree = >+ talloc_get_type_abort(private_data, >+ struct smb2_tree); >+ >+ smbXcli_conn_disconnect(tree->session->transport->conn, >+ NT_STATUS_CTX_CLIENT_QUERY_TIMEOUT); >+} >+ >+/* >+ * Check that Samba3 correctly deals with conflicting local posix byte range >+ * locks on an underlying file via "normal" SMB2 (without posix extentions). >+ * >+ * Note: This test depends on "posix locking = yes". >+ * Note: To run this test, use "--option=torture:localdir=<LOCALDIR>" >+ */ >+static bool torture_samba3_localposixlock1(struct torture_context *tctx, >+ struct smb2_tree *tree) >+{ >+ NTSTATUS status; >+ bool ret = true; >+ int rc; >+ const char *fname = "posixtimedlock.dat"; >+ const char *fpath; >+ const char *localdir; >+ const char *localname; >+ struct smb2_handle h = {{0}}; >+ struct smb2_lock lck = {0}; >+ struct smb2_lock_element el[1] = {{0}}; >+ struct smb2_request *req = NULL; >+ int fd = -1; >+ struct flock posix_lock; >+ struct tevent_timer *te; >+ >+ status = torture_smb2_testdir(tree, BASEDIR, &h); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ smb2_util_close(tree, h); >+ >+ status = torture_smb2_testfile(tree, fname, &h); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ fpath = talloc_asprintf(tctx, "%s\\%s", BASEDIR, fname); >+ torture_assert(tctx, fpath != NULL, "fpath\n"); >+ >+ status = torture_smb2_testfile(tree, fpath, &h); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ localdir = torture_setting_string(tctx, "localdir", NULL); >+ torture_assert(tctx, localdir != NULL, >+ "--option=torture:localdir=<LOCALDIR> required\n"); >+ >+ localname = talloc_asprintf(tctx, "%s/%s/%s", >+ localdir, BASEDIR, fname); >+ torture_assert(tctx, localname != NULL, "localname\n"); >+ >+ /* >+ * Lock a byte range from posix >+ */ >+ >+ torture_comment(tctx, " local open(%s)\n", localname); >+ fd = open(localname, O_RDWR); >+ if (fd == -1) { >+ torture_warning(tctx, "open(%s) failed: %s\n", >+ localname, strerror(errno)); >+ torture_assert(tctx, fd != -1, "open localname\n"); >+ } >+ >+ posix_lock.l_type = F_WRLCK; >+ posix_lock.l_whence = SEEK_SET; >+ posix_lock.l_start = 0; >+ posix_lock.l_len = 1; >+ >+ torture_comment(tctx, " local fcntl\n"); >+ rc = fcntl(fd, F_SETLK, &posix_lock); >+ if (rc == -1) { >+ torture_warning(tctx, "fcntl failed: %s\n", strerror(errno)); >+ torture_assert(tctx, rc != -1, "fcntl lock\n"); >+ } >+ >+ el[0].offset = 0; >+ el[0].length = 1; >+ el[0].reserved = 0x00000000; >+ el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE | >+ SMB2_LOCK_FLAG_FAIL_IMMEDIATELY; >+ lck.in.locks = el; >+ lck.in.lock_count = 0x0001; >+ lck.in.lock_sequence = 0x00000000; >+ lck.in.file.handle = h; >+ >+ torture_comment(tctx, " remote non-blocking lock\n"); >+ status = smb2_lock(tree, &lck); >+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); >+ >+ torture_comment(tctx, " remote async blocking lock\n"); >+ el[0].flags = SMB2_LOCK_FLAG_EXCLUSIVE; >+ req = smb2_lock_send(tree, &lck); >+ torture_assert(tctx, req != NULL, "smb2_lock_send()\n"); >+ >+ te = tevent_add_timer(tctx->ev, >+ tctx, timeval_current_ofs(5, 0), >+ torture_smb2_tree_disconnect_timer, >+ tree); >+ torture_assert(tctx, te != NULL, "tevent_add_timer\n"); >+ >+ torture_comment(tctx, " remote wait for STATUS_PENDING\n"); >+ WAIT_FOR_ASYNC_RESPONSE(req); >+ >+ torture_comment(tctx, " local close file\n"); >+ close(fd); >+ fd = -1; >+ >+ torture_comment(tctx, " remote lock should now succeed\n"); >+ status = smb2_lock_recv(req, &lck); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+done: >+ if (fd != -1) { >+ close(fd); >+ } >+ smb2_util_close(tree, h); >+ smb2_deltree(tree, BASEDIR); >+ return ret; >+} >+ >+struct torture_suite *torture_smb2_samba3misc_init(TALLOC_CTX *ctx) >+{ >+ struct torture_suite *suite = torture_suite_create(ctx, "samba3misc"); >+ >+ torture_suite_add_1smb2_test(suite, "localposixlock1", >+ torture_samba3_localposixlock1); >+ >+ suite->description = talloc_strdup(suite, "SMB2 Samba3 MISC"); >+ >+ return suite; >+} >diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c >index f495c19d251..e57dba3c1d9 100644 >--- a/source4/torture/smb2/smb2.c >+++ b/source4/torture/smb2/smb2.c >@@ -195,6 +195,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) > > torture_suite_add_suite(suite, torture_smb2_doc_init(suite)); > torture_suite_add_suite(suite, torture_smb2_multichannel_init(suite)); >+ torture_suite_add_suite(suite, torture_smb2_samba3misc_init(suite)); > > suite->description = talloc_strdup(suite, "SMB2-specific tests"); > >diff --git a/source4/torture/smb2/wscript_build b/source4/torture/smb2/wscript_build >index e605a4589ac..8b17cfb36d4 100644 >--- a/source4/torture/smb2/wscript_build >+++ b/source4/torture/smb2/wscript_build >@@ -34,6 +34,7 @@ bld.SAMBA_MODULE('TORTURE_SMB2', > sharemode.c > smb2.c > streams.c >+ samba3misc.c > util.c > ''', > subsystem='smbtorture', >-- >2.17.1 > > >From c4d7c186aca3b9fb42354ac47f10514468b4c8b7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 2 Aug 2019 14:50:27 +0200 >Subject: [PATCH 161/376] s3:smb2_lock: add retry for POSIX locks > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8decf41bbb8be2b4ac463eb6ace16a8628276ab5) >--- > selftest/knownfail.d/smb2.localposixlock | 1 - > source3/smbd/smb2_lock.c | 55 ++++++++++++++++++++++++ > 2 files changed, 55 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/smb2.localposixlock > >diff --git a/selftest/knownfail.d/smb2.localposixlock b/selftest/knownfail.d/smb2.localposixlock >deleted file mode 100644 >index 1b84f074e0b..00000000000 >--- a/selftest/knownfail.d/smb2.localposixlock >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smb2.samba3misc.localposixlock1 >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index a8ccf21cc20..8ba54fe6995 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -43,6 +43,7 @@ struct smbd_smb2_lock_state { > struct smb_request *smb1req; > struct files_struct *fsp; > bool blocking; >+ uint32_t polling_msecs; > uint16_t lock_count; > struct smbd_lock_element *locks; > }; >@@ -371,6 +372,32 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return req; > } > >+static void smbd_smb2_lock_update_polling_msecs( >+ struct smbd_smb2_lock_state *state) >+{ >+ /* >+ * The default lp_lock_spin_time() is 200ms. >+ * >+ * v_min is in the range of 0.002 to 20 secs >+ * (0.2 secs by default) >+ * >+ * v_max is in the range of 0.02 to 200 secs >+ * (2.0 secs by default) >+ * >+ * The typical steps are: >+ * 0.2, 0.4, 0.6, 0.8, ... 2.0 >+ */ >+ uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time())); >+ uint32_t v_max = 10 * v_min; >+ >+ if (state->polling_msecs >= v_max) { >+ state->polling_msecs = v_max; >+ return; >+ } >+ >+ state->polling_msecs += v_min; >+} >+ > static void smbd_smb2_lock_try(struct tevent_req *req) > { > struct smbd_smb2_lock_state *state = tevent_req_data( >@@ -381,6 +408,7 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > uint64_t blocking_smblctx; > NTSTATUS status; > struct tevent_req *subreq = NULL; >+ struct timeval endtime = { 0 }; > > lck = get_existing_share_mode_lock( > talloc_tos(), state->fsp->file_id); >@@ -426,6 +454,15 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > return; > } > >+ if (blocking_smblctx == UINT64_MAX) { >+ smbd_smb2_lock_update_polling_msecs(state); >+ >+ DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", >+ state->polling_msecs); >+ >+ endtime = timeval_current_ofs_msec(state->polling_msecs); >+ } >+ > DBG_DEBUG("Watching share mode lock\n"); > > subreq = dbwrap_watched_watch_send( >@@ -435,6 +472,18 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > return; > } > tevent_req_set_callback(subreq, smbd_smb2_lock_retry, req); >+ >+ if (!timeval_is_zero(&endtime)) { >+ bool ok; >+ >+ ok = tevent_req_set_endtime(subreq, >+ state->ev, >+ endtime); >+ if (!ok) { >+ tevent_req_oom(req); >+ return; >+ } >+ } > } > > static void smbd_smb2_lock_retry(struct tevent_req *subreq) >@@ -457,6 +506,12 @@ static void smbd_smb2_lock_retry(struct tevent_req *subreq) > > status = dbwrap_watched_watch_recv(subreq, NULL, NULL); > TALLOC_FREE(subreq); >+ if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { >+ /* >+ * This is just a trigger for a timed retry. >+ */ >+ status = NT_STATUS_OK; >+ } > if (tevent_req_nterror(req, status)) { > return; > } >-- >2.17.1 > > >From da765a062aa4b57814ea426c94c6b3ba23dca47c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 12:28:39 +0200 >Subject: [PATCH 162/376] s4:torture/raw: improvements for multilock2 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8a7039be530adcdda9e7e7621bdcf902f5ca1721) >--- > source4/torture/raw/lock.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c >index f1fbdd6da71..f264d0aea11 100644 >--- a/source4/torture/raw/lock.c >+++ b/source4/torture/raw/lock.c >@@ -2449,7 +2449,7 @@ static bool test_multilock2(struct torture_context *tctx, > lock[0].pid = cli->session->pid+2; > io.lockx.in.lock_cnt = 1; > req2 = smb_raw_lock_send(cli->tree, &io); >- torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, >+ torture_assert(tctx,(req2 != NULL), talloc_asprintf(tctx, > "Failed to setup timed locks (%s)\n", __location__)); > > /* Unlock lock[0] */ >@@ -2465,6 +2465,9 @@ static bool test_multilock2(struct torture_context *tctx, > status = smbcli_request_simple_recv(req2); > CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); > >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ > /* Start the clock. */ > t = time_mono(NULL); > >-- >2.17.1 > > >From 6bd411aad81477637255fcb5c826ddaf43f593b1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 12:13:15 +0200 >Subject: [PATCH 163/376] s4:torture/raw: add multilock3 test > >This demonstrates that unrelated lock ranges >are not blocked by other blocked requests on the same >fsp. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 297763c6b618c07148d788b46218a0798225bf79) >--- > selftest/knownfail.d/multilock | 1 + > source4/torture/raw/lock.c | 266 +++++++++++++++++++++++++++++++++ > 2 files changed, 267 insertions(+) > create mode 100644 selftest/knownfail.d/multilock > >diff --git a/selftest/knownfail.d/multilock b/selftest/knownfail.d/multilock >new file mode 100644 >index 00000000000..e0e6e81c453 >--- /dev/null >+++ b/selftest/knownfail.d/multilock >@@ -0,0 +1 @@ >+^samba3.raw.lock.multilock3.*nt4_dc >diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c >index f264d0aea11..bea55f6a605 100644 >--- a/source4/torture/raw/lock.c >+++ b/source4/torture/raw/lock.c >@@ -2494,6 +2494,271 @@ done: > return ret; > } > >+/* >+ test multi3 Locking&X operation >+ This test is designed to show that >+ lock precedence on the server is based >+ on the order received, not on the ability >+ to grant. >+ >+ Compared to test_multilock2() (above) >+ this test demonstrates that completely >+ unrelated ranges work independently. >+ >+ For example: >+ >+ A blocked lock request containing 2 locks >+ will be satified before a subsequent blocked >+ lock request over one of the same regions, >+ even if that region is then unlocked. But >+ a lock of a different region goes through. E.g. >+ >+ All locks are LOCKING_ANDX_EXCLUSIVE_LOCK (rw). >+ >+ (a) lock 100->109, 120->129 (granted) >+ (b) lock 100->109, 120->129 (blocks, timeout=20s) >+ (c) lock 100->109 (blocks, timeout=2s) >+ (d) lock 110->119 (granted) >+ (e) lock 110->119 (blocks, timeout=20s) >+ (f) unlock 100->109 (a) >+ (g) lock 100->109 (not granted, blocked by (b)) >+ (h) lock 100->109 (not granted, blocked by itself (b)) >+ (i) lock (c) will not be granted(conflict, times out) >+ as lock (b) will take precedence. >+ (j) unlock 110-119 (d) >+ (k) lock (e) completes and is not blocked by (a) nor (b) >+ (l) lock 100->109 (not granted(conflict), blocked by (b)) >+ (m) lock 100->109 (not granted(conflict), blocked by itself (b)) >+ (n) unlock 120-129 (a) >+ (o) lock (b) completes >+*/ >+static bool test_multilock3(struct torture_context *tctx, >+ struct smbcli_state *cli) >+{ >+ union smb_lock io; >+ struct smb_lock_entry lock[2]; >+ union smb_lock io3; >+ struct smb_lock_entry lock3[1]; >+ NTSTATUS status; >+ bool ret = true; >+ int fnum; >+ const char *fname = BASEDIR "\\multilock3_test.txt"; >+ time_t t; >+ struct smbcli_request *req = NULL; >+ struct smbcli_request *req2 = NULL; >+ struct smbcli_request *req4 = NULL; >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), >+ "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Testing LOCKING_ANDX multi-lock 3\n"); >+ io.generic.level = RAW_LOCK_LOCKX; >+ >+ /* Create the test file. */ >+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx, >+ "Failed to create %s - %s\n", >+ fname, smbcli_errstr(cli->tree))); >+ >+ /* >+ * a) >+ * Lock regions 100->109, 120->129 as >+ * two separate write locks in one request. >+ */ >+ io.lockx.level = RAW_LOCK_LOCKX; >+ io.lockx.in.file.fnum = fnum; >+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 2; >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock[0].pid = cli->session->pid; >+ lock[0].offset = 100; >+ lock[0].count = 10; >+ lock[1].pid = cli->session->pid; >+ lock[1].offset = 120; >+ lock[1].count = 10; >+ io.lockx.in.locks = &lock[0]; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * b) >+ * Now request the same locks on a different >+ * context as blocking locks. >+ */ >+ io.lockx.in.timeout = 20000; >+ lock[0].pid = cli->session->pid+1; >+ lock[1].pid = cli->session->pid+1; >+ req = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * c) >+ * Request the first lock again on a separate context. >+ * Wait 2 seconds. This should time out (the previous >+ * multi-lock request should take precedence). >+ */ >+ io.lockx.in.timeout = 2000; >+ lock[0].pid = cli->session->pid+2; >+ io.lockx.in.lock_cnt = 1; >+ req2 = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req2 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * d) >+ * Lock regions 110->119 >+ */ >+ io3.lockx.level = RAW_LOCK_LOCKX; >+ io3.lockx.in.file.fnum = fnum; >+ io3.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 0; >+ io3.lockx.in.lock_cnt = 1; >+ io3.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock3[0].pid = cli->session->pid+3; >+ lock3[0].offset = 110; >+ lock3[0].count = 10; >+ io3.lockx.in.locks = &lock3[0]; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * e) >+ * try 110-119 again >+ */ >+ io3.lockx.in.timeout = 20000; >+ lock3[0].pid = cli->session->pid+4; >+ req4 = smb_raw_lock_send(cli->tree, &io3); >+ torture_assert(tctx,(req4 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * f) >+ * Unlock (a) lock[0] 100-109 >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[0]; >+ lock[0].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * g) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+5; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); >+ >+ /* >+ * h) >+ * try to lock lock[0] 100-109 again with >+ * the pid that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req2->state <= SMBCLI_REQUEST_RECV, >+ "req2 should still wait"); >+ >+ /* >+ * i) >+ * Did the second lock complete (should time out) ? >+ */ >+ status = smbcli_request_simple_recv(req2); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ torture_assert(tctx, req4->state <= SMBCLI_REQUEST_RECV, >+ "req4 should still wait"); >+ >+ /* >+ * j) >+ * Unlock (d) lock[0] 110-119 >+ */ >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 1; >+ io3.lockx.in.lock_cnt = 0; >+ lock3[0].pid = cli->session->pid+3; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * k) >+ * receive the successful blocked lock request (e) >+ * on 110-119 while the 100-109/120-129 is still waiting. >+ */ >+ status = smbcli_request_simple_recv(req4); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * l) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+6; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ >+ /* >+ * m) >+ * try to lock lock[0] 100-109 again with >+ * the pid that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ >+ /* Start the clock. */ >+ t = time_mono(NULL); >+ >+ /* >+ * n) >+ * Unlock lock[1] 120-129 */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[1]; >+ lock[1].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * o) >+ * receive the successful blocked lock request (b) >+ */ >+ status = smbcli_request_simple_recv(req); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* Fail if this took more than 2 seconds. */ >+ torture_assert(tctx,!(time_mono(NULL) > t+2), talloc_asprintf(tctx, >+ "Blocking locks were not granted immediately (%s)\n", >+ __location__)); >+done: >+ smb_raw_exit(cli->session); >+ smbcli_deltree(cli->tree, BASEDIR); >+ return ret; >+} > > /* > basic testing of lock calls >@@ -2517,6 +2782,7 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx) > torture_suite_add_1smb_test(suite, "zerobyteread", test_zerobyteread); > torture_suite_add_1smb_test(suite, "multilock", test_multilock); > torture_suite_add_1smb_test(suite, "multilock2", test_multilock2); >+ torture_suite_add_1smb_test(suite, "multilock3", test_multilock3); > > return suite; > } >-- >2.17.1 > > >From cc9afc3dac2fd680fd5731160889fc39eb0e360c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 14:49:29 +0200 >Subject: [PATCH 164/376] s4:torture/raw: add multilock4 test > >This is similar to multilock3, but uses read-only >(LOCKING_ANDX_SHARED_LOCK) locks for the blocked >requests. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit d3e65ceb1ec25c7b62a7e908506126269011f30d) >--- > selftest/knownfail.d/multilock | 1 + > source4/torture/raw/lock.c | 266 +++++++++++++++++++++++++++++++++ > 2 files changed, 267 insertions(+) > >diff --git a/selftest/knownfail.d/multilock b/selftest/knownfail.d/multilock >index e0e6e81c453..01538acc5a8 100644 >--- a/selftest/knownfail.d/multilock >+++ b/selftest/knownfail.d/multilock >@@ -1 +1,2 @@ > ^samba3.raw.lock.multilock3.*nt4_dc >+^samba3.raw.lock.multilock4.*nt4_dc >diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c >index bea55f6a605..26339f9b28b 100644 >--- a/source4/torture/raw/lock.c >+++ b/source4/torture/raw/lock.c >@@ -2760,6 +2760,271 @@ done: > return ret; > } > >+/* >+ test multi4 Locking&X operation >+ This test is designed to show that >+ lock precedence on the server is based >+ on the order received, not on the ability >+ to grant. >+ >+ Compared to test_multilock3() (above) >+ this test demonstrates that pending read-only/shared >+ locks doesn't block shared locks others. >+ >+ The outstanding requests build an implicit >+ database that's checked before checking >+ the already granted locks in the real database. >+ >+ For example: >+ >+ A blocked read-lock request containing 2 locks >+ will be still be blocked, while one region >+ is still write-locked. While it doesn't block >+ other read-lock requests for the other region. E.g. >+ >+ (a) lock(rw) 100->109, 120->129 (granted) >+ (b) lock(ro) 100->109, 120->129 (blocks, timeout=20s) >+ (c) lock(ro) 100->109 (blocks, timeout=MAX) >+ (d) lock(rw) 110->119 (granted) >+ (e) lock(rw) 110->119 (blocks, timeout=20s) >+ (f) unlock 100->109 (a) >+ (g) lock(ro) (c) completes and is not blocked by (a) nor (b) >+ (h) lock(rw) 100->109 (not granted, blocked by (c)) >+ (i) lock(rw) 100->109 (pid (b)) (not granted(conflict), blocked by (c)) >+ (j) unlock 110-119 >+ (k) lock (e) completes and is not blocked by (a) nor (b) >+ (l) lock 100->109 (not granted(conflict), blocked by (b)) >+ (m) lock 100->109 (pid (b)) (not granted(conflict), blocked by itself (b)) >+ (n) unlock 120-129 (a) >+ (o) lock (b) completes >+*/ >+static bool test_multilock4(struct torture_context *tctx, >+ struct smbcli_state *cli) >+{ >+ union smb_lock io; >+ struct smb_lock_entry lock[2]; >+ union smb_lock io3; >+ struct smb_lock_entry lock3[1]; >+ NTSTATUS status; >+ bool ret = true; >+ int fnum; >+ const char *fname = BASEDIR "\\multilock4_test.txt"; >+ time_t t; >+ struct smbcli_request *req = NULL; >+ struct smbcli_request *req2 = NULL; >+ struct smbcli_request *req4 = NULL; >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), >+ "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Testing LOCKING_ANDX multi-lock 4\n"); >+ io.generic.level = RAW_LOCK_LOCKX; >+ >+ /* Create the test file. */ >+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx, >+ "Failed to create %s - %s\n", >+ fname, smbcli_errstr(cli->tree))); >+ >+ /* >+ * a) >+ * Lock regions 100->109, 120->129 as >+ * two separate write locks in one request. >+ */ >+ io.lockx.level = RAW_LOCK_LOCKX; >+ io.lockx.in.file.fnum = fnum; >+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 2; >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock[0].pid = cli->session->pid; >+ lock[0].offset = 100; >+ lock[0].count = 10; >+ lock[1].pid = cli->session->pid; >+ lock[1].offset = 120; >+ lock[1].count = 10; >+ io.lockx.in.locks = &lock[0]; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * b) >+ * Now request the same locks on a different >+ * context as blocking locks. But readonly. >+ */ >+ io.lockx.in.timeout = 20000; >+ io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; >+ lock[0].pid = cli->session->pid+1; >+ lock[1].pid = cli->session->pid+1; >+ req = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * c) >+ * Request the first lock again on a separate context. >+ * Wait forever. The previous multi-lock request (b) >+ * should take precedence. Also readonly. >+ */ >+ io.lockx.in.timeout = UINT32_MAX; >+ lock[0].pid = cli->session->pid+2; >+ io.lockx.in.lock_cnt = 1; >+ req2 = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req2 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * d) >+ * Lock regions 110->119 >+ */ >+ io3.lockx.level = RAW_LOCK_LOCKX; >+ io3.lockx.in.file.fnum = fnum; >+ io3.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 0; >+ io3.lockx.in.lock_cnt = 1; >+ io3.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock3[0].pid = cli->session->pid+3; >+ lock3[0].offset = 110; >+ lock3[0].count = 10; >+ io3.lockx.in.locks = &lock3[0]; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * e) >+ * try 110-119 again >+ */ >+ io3.lockx.in.timeout = 20000; >+ lock3[0].pid = cli->session->pid+4; >+ req4 = smb_raw_lock_send(cli->tree, &io3); >+ torture_assert(tctx,(req4 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * f) >+ * Unlock (a) lock[0] 100-109 >+ */ >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[0]; >+ lock[0].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * g) >+ * receive the successful blocked lock request (c) >+ * on 110-119 while (b) 100-109/120-129 is still waiting. >+ */ >+ status = smbcli_request_simple_recv(req2); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * h) >+ * try to lock lock[0] 100-109 again >+ * (read/write) >+ */ >+ lock[0].pid = cli->session->pid+5; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); >+ >+ /* >+ * i) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting. >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ torture_assert(tctx, req4->state <= SMBCLI_REQUEST_RECV, >+ "req4 should still wait"); >+ >+ /* >+ * j) >+ * Unlock (d) lock[0] 110-119 >+ */ >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 1; >+ io3.lockx.in.lock_cnt = 0; >+ lock3[0].pid = cli->session->pid+3; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * k) >+ * receive the successful blocked >+ * lock request (e) on 110-119. >+ */ >+ status = smbcli_request_simple_recv(req4); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * l) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+6; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ /* >+ * m) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ >+ /* Start the clock. */ >+ t = time_mono(NULL); >+ >+ /* >+ * n) >+ * Unlock (a) lock[1] 120-129 >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[1]; >+ lock[1].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * o) >+ * receive the successful blocked lock request (b) >+ */ >+ status = smbcli_request_simple_recv(req); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* Fail if this took more than 2 seconds. */ >+ torture_assert(tctx,!(time_mono(NULL) > t+2), talloc_asprintf(tctx, >+ "Blocking locks were not granted immediately (%s)\n", >+ __location__)); >+done: >+ smb_raw_exit(cli->session); >+ smbcli_deltree(cli->tree, BASEDIR); >+ return ret; >+} >+ > /* > basic testing of lock calls > */ >@@ -2783,6 +3048,7 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx) > torture_suite_add_1smb_test(suite, "multilock", test_multilock); > torture_suite_add_1smb_test(suite, "multilock2", test_multilock2); > torture_suite_add_1smb_test(suite, "multilock3", test_multilock3); >+ torture_suite_add_1smb_test(suite, "multilock4", test_multilock4); > > return suite; > } >-- >2.17.1 > > >From a037ebbc34795de46196ff50ad439356056fe082 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 15:12:01 +0200 >Subject: [PATCH 165/376] s4:torture/raw: add multilock5 test > >This is similar to multilock3, but uses a read-only >(LOCKING_ANDX_SHARED_LOCK) locks for the first lock >request. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 6d4296aca0c9a9287c0c78c8f8847a560bd2ea24) >--- > selftest/knownfail.d/multilock | 1 + > source4/torture/raw/lock.c | 269 +++++++++++++++++++++++++++++++++ > 2 files changed, 270 insertions(+) > >diff --git a/selftest/knownfail.d/multilock b/selftest/knownfail.d/multilock >index 01538acc5a8..b3fe93fd34e 100644 >--- a/selftest/knownfail.d/multilock >+++ b/selftest/knownfail.d/multilock >@@ -1,2 +1,3 @@ > ^samba3.raw.lock.multilock3.*nt4_dc > ^samba3.raw.lock.multilock4.*nt4_dc >+^samba3.raw.lock.multilock5.*nt4_dc >diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c >index 26339f9b28b..c29a577b34a 100644 >--- a/source4/torture/raw/lock.c >+++ b/source4/torture/raw/lock.c >@@ -3025,6 +3025,274 @@ done: > return ret; > } > >+/* >+ test multi5 Locking&X operation >+ This test is designed to show that >+ lock precedence on the server is based >+ on the order received, not on the ability >+ to grant. >+ >+ Compared to test_multilock3() (above) >+ this test demonstrates that the initial >+ lock request that block the following >+ exclusive locks can be a shared lock. >+ >+ For example: >+ >+ All locks except (a) are LOCKING_ANDX_EXCLUSIVE_LOCK (rw). >+ >+ (a) lock(ro) 100->109, 120->129 (granted) >+ (b) lock 100->109, 120->129 (blocks, timeout=20s) >+ (c) lock 100->109 (blocks, timeout=2s) >+ (d) lock 110->119 (granted) >+ (e) lock 110->119 (blocks, timeout=20s) >+ (f) unlock 100->109 (a) >+ (g) lock 100->109 (not granted, blocked by (b)) >+ (h) lock 100->109 (not granted, blocked by itself (b)) >+ (i) lock (c) will not be granted(conflict, times out) >+ as lock (b) will take precedence. >+ (j) unlock 110-119 (d) >+ (k) lock (e) completes and is not blocked by (a) nor (b) >+ (l) lock 100->109 (not granted(conflict), blocked by (b)) >+ (m) lock 100->109 (not granted(conflict), blocked by itself (b)) >+ (n) unlock 120-129 (a) >+ (o) lock (b) completes >+*/ >+static bool test_multilock5(struct torture_context *tctx, >+ struct smbcli_state *cli) >+{ >+ union smb_lock io; >+ struct smb_lock_entry lock[2]; >+ union smb_lock io3; >+ struct smb_lock_entry lock3[1]; >+ NTSTATUS status; >+ bool ret = true; >+ int fnum; >+ const char *fname = BASEDIR "\\multilock5_test.txt"; >+ time_t t; >+ struct smbcli_request *req = NULL; >+ struct smbcli_request *req2 = NULL; >+ struct smbcli_request *req4 = NULL; >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), >+ "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Testing LOCKING_ANDX multi-lock 5\n"); >+ io.generic.level = RAW_LOCK_LOCKX; >+ >+ /* Create the test file. */ >+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx, >+ "Failed to create %s - %s\n", >+ fname, smbcli_errstr(cli->tree))); >+ >+ /* >+ * a) >+ * Lock regions 100->109, 120->129 as >+ * two separate write locks in one request. >+ * (read only) >+ */ >+ io.lockx.level = RAW_LOCK_LOCKX; >+ io.lockx.in.file.fnum = fnum; >+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 2; >+ io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; >+ lock[0].pid = cli->session->pid; >+ lock[0].offset = 100; >+ lock[0].count = 10; >+ lock[1].pid = cli->session->pid; >+ lock[1].offset = 120; >+ lock[1].count = 10; >+ io.lockx.in.locks = &lock[0]; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * b) >+ * Now request the same locks on a different >+ * context as blocking locks. >+ * (read write) >+ */ >+ io.lockx.in.timeout = 20000; >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock[0].pid = cli->session->pid+1; >+ lock[1].pid = cli->session->pid+1; >+ req = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * c) >+ * Request the first lock again on a separate context. >+ * Wait 2 seconds. This should time out (the previous >+ * multi-lock request should take precedence). >+ * (read write) >+ */ >+ io.lockx.in.timeout = 2000; >+ lock[0].pid = cli->session->pid+2; >+ io.lockx.in.lock_cnt = 1; >+ req2 = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req2 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * d) >+ * Lock regions 110->119 >+ */ >+ io3.lockx.level = RAW_LOCK_LOCKX; >+ io3.lockx.in.file.fnum = fnum; >+ io3.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 0; >+ io3.lockx.in.lock_cnt = 1; >+ io3.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock3[0].pid = cli->session->pid+3; >+ lock3[0].offset = 110; >+ lock3[0].count = 10; >+ io3.lockx.in.locks = &lock3[0]; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * e) >+ * try 110-119 again >+ */ >+ io3.lockx.in.timeout = 20000; >+ lock3[0].pid = cli->session->pid+4; >+ req4 = smb_raw_lock_send(cli->tree, &io3); >+ torture_assert(tctx,(req4 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * f) >+ * Unlock (a) lock[0] 100-109 >+ * >+ * Note we send LOCKING_ANDX_EXCLUSIVE_LOCK >+ * while the lock used LOCKING_ANDX_SHARED_LOCK >+ * to check if that also works. >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[0]; >+ lock[0].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * g) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+5; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); >+ >+ /* >+ * h) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting. >+ * (read write) >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req2->state <= SMBCLI_REQUEST_RECV, >+ "req2 should still wait"); >+ >+ /* >+ * i) >+ * Did the second lock complete (should time out) ? >+ */ >+ status = smbcli_request_simple_recv(req2); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ torture_assert(tctx, req4->state <= SMBCLI_REQUEST_RECV, >+ "req4 should still wait"); >+ >+ /* >+ * j) >+ * Unlock (d) lock[0] 110-119 >+ */ >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 1; >+ io3.lockx.in.lock_cnt = 0; >+ lock3[0].pid = cli->session->pid+3; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * k) >+ * receive the successful blocked lock requests >+ * on 110-119 while the 100-109/120-129 is still waiting. >+ */ >+ status = smbcli_request_simple_recv(req4); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * l) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+6; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ /* >+ * m) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ >+ /* Start the clock. */ >+ t = time_mono(NULL); >+ >+ /* >+ * n) >+ * Unlock (a) lock[1] 120-129 >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[1]; >+ lock[1].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * o) >+ * receive the successful blocked lock request (b) >+ */ >+ status = smbcli_request_simple_recv(req); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* Fail if this took more than 2 seconds. */ >+ torture_assert(tctx,!(time_mono(NULL) > t+2), talloc_asprintf(tctx, >+ "Blocking locks were not granted immediately (%s)\n", >+ __location__)); >+done: >+ smb_raw_exit(cli->session); >+ smbcli_deltree(cli->tree, BASEDIR); >+ return ret; >+} >+ > /* > basic testing of lock calls > */ >@@ -3049,6 +3317,7 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx) > torture_suite_add_1smb_test(suite, "multilock2", test_multilock2); > torture_suite_add_1smb_test(suite, "multilock3", test_multilock3); > torture_suite_add_1smb_test(suite, "multilock4", test_multilock4); >+ torture_suite_add_1smb_test(suite, "multilock5", test_multilock5); > > return suite; > } >-- >2.17.1 > > >From d857b21d4fec18aa71f9bec4343924053dd9f083 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 16:24:34 +0200 >Subject: [PATCH 166/376] s4:torture/raw: add multilock6 test > >This is similar to multilock3, but uses a read-only >(LOCKING_ANDX_SHARED_LOCK) locks for the 2nd lock >request. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit d3bc0199697fd7d6e04479321ca644a227bc4ede) >--- > selftest/knownfail | 1 + > selftest/knownfail.d/multilock | 1 + > source4/torture/raw/lock.c | 263 +++++++++++++++++++++++++++++++++ > 3 files changed, 265 insertions(+) > >diff --git a/selftest/knownfail b/selftest/knownfail >index ded80b12259..7b54b77a708 100644 >--- a/selftest/knownfail >+++ b/selftest/knownfail >@@ -109,6 +109,7 @@ > .*net.api.delshare.* # DelShare isn't implemented yet > ^samba4.smb2.oplock.doc > ^samba4.smb2.lock.valid-request >+^samba4.raw.lock.multilock6.ad_dc_ntvfs > ^samba4.ldap.python \(ad_dc_default\).Test add_ldif\(\) with BASE64 security descriptor input using WRONG domain SID\(.*\)$ > ^samba4.raw.lock.*.async # bug 6960 > ^samba4.raw.open.ntcreatex_supersede >diff --git a/selftest/knownfail.d/multilock b/selftest/knownfail.d/multilock >index b3fe93fd34e..9fa497bd643 100644 >--- a/selftest/knownfail.d/multilock >+++ b/selftest/knownfail.d/multilock >@@ -1,3 +1,4 @@ > ^samba3.raw.lock.multilock3.*nt4_dc > ^samba3.raw.lock.multilock4.*nt4_dc > ^samba3.raw.lock.multilock5.*nt4_dc >+^samba3.raw.lock.multilock6.*nt4_dc >diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c >index c29a577b34a..f684e923a49 100644 >--- a/source4/torture/raw/lock.c >+++ b/source4/torture/raw/lock.c >@@ -3293,6 +3293,268 @@ done: > return ret; > } > >+/* >+ test multi6 Locking&X operation >+ This test is designed to show that >+ lock precedence on the server is based >+ on the order received, not on the ability >+ to grant. >+ >+ Compared to test_multilock4() (above) >+ this test demonstrates the behavior if >+ only just the first blocking lock >+ being a shared lock. >+ >+ For example: >+ >+ All locks except (b) are LOCKING_ANDX_EXCLUSIVE_LOCK (rw). >+ >+ (a) lock 100->109, 120->129 (granted) >+ (b) lock(ro) 100->109, 120->129 (blocks, timeout=20s) >+ (c) lock 100->109 (blocks, timeout=2s) >+ (d) lock 110->119 (granted) >+ (e) lock 110->119 (blocks, timeout=20s) >+ (f) unlock 100->109 (a) >+ (g) lock 100->109 (not granted, blocked by (b)) >+ (h) lock 100->109 (not granted, blocked by itself (b)) >+ (i) lock (c) will not be granted(conflict, times out) >+ as lock (b) will take precedence. >+ (j) unlock 110-119 (d) >+ (k) lock (e) completes and is not blocked by (a) nor (b) >+ (l) lock 100->109 (not granted(conflict), blocked by (b)) >+ (m) lock 100->109 (not granted(conflict), blocked by itself (b)) >+ (n) unlock 120-129 (a) >+ (o) lock (b) completes >+*/ >+static bool test_multilock6(struct torture_context *tctx, >+ struct smbcli_state *cli) >+{ >+ union smb_lock io; >+ struct smb_lock_entry lock[2]; >+ union smb_lock io3; >+ struct smb_lock_entry lock3[1]; >+ NTSTATUS status; >+ bool ret = true; >+ int fnum; >+ const char *fname = BASEDIR "\\multilock6_test.txt"; >+ time_t t; >+ struct smbcli_request *req = NULL; >+ struct smbcli_request *req2 = NULL; >+ struct smbcli_request *req4 = NULL; >+ >+ torture_assert(tctx, torture_setup_dir(cli, BASEDIR), >+ "Failed to setup up test directory: " BASEDIR); >+ >+ torture_comment(tctx, "Testing LOCKING_ANDX multi-lock 6\n"); >+ io.generic.level = RAW_LOCK_LOCKX; >+ >+ /* Create the test file. */ >+ fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); >+ torture_assert(tctx,(fnum != -1), talloc_asprintf(tctx, >+ "Failed to create %s - %s\n", >+ fname, smbcli_errstr(cli->tree))); >+ >+ /* >+ * a) >+ * Lock regions 100->109, 120->129 as >+ * two separate write locks in one request. >+ */ >+ io.lockx.level = RAW_LOCK_LOCKX; >+ io.lockx.in.file.fnum = fnum; >+ io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 2; >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock[0].pid = cli->session->pid; >+ lock[0].offset = 100; >+ lock[0].count = 10; >+ lock[1].pid = cli->session->pid; >+ lock[1].offset = 120; >+ lock[1].count = 10; >+ io.lockx.in.locks = &lock[0]; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * b) >+ * Now request the same locks on a different >+ * context as blocking locks. >+ * (read only) >+ */ >+ io.lockx.in.timeout = 20000; >+ io.lockx.in.mode = LOCKING_ANDX_SHARED_LOCK; >+ lock[0].pid = cli->session->pid+1; >+ lock[1].pid = cli->session->pid+1; >+ req = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * c) >+ * Request the first lock again on a separate context. >+ * Wait 2 seconds. This should time out (the previous >+ * multi-lock request should take precedence). >+ */ >+ io.lockx.in.timeout = 2000; >+ io.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock[0].pid = cli->session->pid+2; >+ io.lockx.in.lock_cnt = 1; >+ req2 = smb_raw_lock_send(cli->tree, &io); >+ torture_assert(tctx,(req2 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * d) >+ * Lock regions 110->119 >+ */ >+ io3.lockx.level = RAW_LOCK_LOCKX; >+ io3.lockx.in.file.fnum = fnum; >+ io3.lockx.in.mode = LOCKING_ANDX_LARGE_FILES; >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 0; >+ io3.lockx.in.lock_cnt = 1; >+ io3.lockx.in.mode = LOCKING_ANDX_EXCLUSIVE_LOCK; >+ lock3[0].pid = cli->session->pid+3; >+ lock3[0].offset = 110; >+ lock3[0].count = 10; >+ io3.lockx.in.locks = &lock3[0]; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * e) >+ * try 110-119 again >+ */ >+ io3.lockx.in.timeout = 20000; >+ lock3[0].pid = cli->session->pid+4; >+ req4 = smb_raw_lock_send(cli->tree, &io3); >+ torture_assert(tctx,(req4 != NULL), talloc_asprintf(tctx, >+ "Failed to setup timed locks (%s)\n", __location__)); >+ >+ /* >+ * f) >+ * Unlock (a) lock[0] 100-109 >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[0]; >+ lock[0].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * g) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+5; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); >+ >+ /* >+ * h) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req2->state <= SMBCLI_REQUEST_RECV, >+ "req2 should still wait"); >+ >+ /* >+ * i) >+ * Did the second lock (c) complete (should time out) ? >+ */ >+ status = smbcli_request_simple_recv(req2); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ torture_assert(tctx, req4->state <= SMBCLI_REQUEST_RECV, >+ "req4 should still wait"); >+ >+ /* >+ * j) >+ * Unlock (d) lock[0] 110-119 >+ */ >+ io3.lockx.in.timeout = 0; >+ io3.lockx.in.ulock_cnt = 1; >+ io3.lockx.in.lock_cnt = 0; >+ lock3[0].pid = cli->session->pid+3; >+ status = smb_raw_lock(cli->tree, &io3); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * k) >+ * receive the successful blocked lock request (e) >+ * on 110-119 while (b) 100-109/120-129 is still waiting. >+ */ >+ status = smbcli_request_simple_recv(req4); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * l) >+ * try to lock lock[0] 100-109 again >+ */ >+ lock[0].pid = cli->session->pid+6; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ /* >+ * m) >+ * try to lock lock[0] 100-109 again with the pid (b) >+ * that's still waiting >+ */ >+ lock[0].pid = cli->session->pid+1; >+ io.lockx.in.ulock_cnt = 0; >+ io.lockx.in.lock_cnt = 1; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); >+ >+ torture_assert(tctx, req->state <= SMBCLI_REQUEST_RECV, >+ "req should still wait"); >+ >+ /* Start the clock. */ >+ t = time_mono(NULL); >+ >+ /* >+ * n) >+ * Unlock (a) lock[1] 120-129 >+ */ >+ io.lockx.in.timeout = 0; >+ io.lockx.in.ulock_cnt = 1; >+ io.lockx.in.lock_cnt = 0; >+ io.lockx.in.locks = &lock[1]; >+ lock[1].pid = cli->session->pid; >+ status = smb_raw_lock(cli->tree, &io); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* >+ * o) >+ * receive the successful blocked lock request (b) >+ */ >+ status = smbcli_request_simple_recv(req); >+ CHECK_STATUS(status, NT_STATUS_OK); >+ >+ /* Fail if this took more than 2 seconds. */ >+ torture_assert(tctx,!(time_mono(NULL) > t+2), talloc_asprintf(tctx, >+ "Blocking locks were not granted immediately (%s)\n", >+ __location__)); >+done: >+ smb_raw_exit(cli->session); >+ smbcli_deltree(cli->tree, BASEDIR); >+ return ret; >+} >+ > /* > basic testing of lock calls > */ >@@ -3318,6 +3580,7 @@ struct torture_suite *torture_raw_lock(TALLOC_CTX *mem_ctx) > torture_suite_add_1smb_test(suite, "multilock3", test_multilock3); > torture_suite_add_1smb_test(suite, "multilock4", test_multilock4); > torture_suite_add_1smb_test(suite, "multilock5", test_multilock5); >+ torture_suite_add_1smb_test(suite, "multilock6", test_multilock6); > > return suite; > } >-- >2.17.1 > > >From 9f46f3b0e722d993a650fc3659e842aad08837a6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 18:17:47 +0200 >Subject: [PATCH 167/376] s3:blocking: use timeval_expired(&state->endtime) to > stop processing > >This is less racy than timeval_elapsed() > 0 >as the current time is already expired and timeout = 0 >will always work correct. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 5a841a43f9c4f862e2d7235429363b3066cf5850) >--- > source3/smbd/blocking.c | 25 +++++++++++++++++-------- > 1 file changed, 17 insertions(+), 8 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index a87d62d910a..9f64a86d3ee 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -159,9 +159,10 @@ struct tevent_req *smbd_smb1_do_locks_send( > struct share_mode_lock *lck = NULL; > struct server_id blocking_pid = { 0 }; > uint64_t blocking_smblctx = 0; >- struct timeval endtime; >+ struct timeval endtime = { 0 }; > NTSTATUS status = NT_STATUS_OK; > bool ok; >+ bool expired; > > req = tevent_req_create( > mem_ctx, &state, struct smbd_smb1_do_locks_state); >@@ -251,19 +252,28 @@ struct tevent_req *smbd_smb1_do_locks_send( > state->timeout = lp_lock_spin_time(); > } > } >+ state->endtime = timeval_current_ofs_msec(state->timeout); > > DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", > state->timeout, > blocking_smblctx); > > /* >+ * The client specified timeout expired >+ * avoid further retries. >+ * >+ * Otherwise keep waiting either waiting >+ * for changes in locking.tdb or the polling >+ * mode timers waiting for posix locks. >+ * > * If the endtime is not elapsed yet, > * it means we'll retry after a timeout. > * In that case we'll have to return > * NT_STATUS_FILE_LOCK_CONFLICT > * instead of NT_STATUS_LOCK_NOT_GRANTED. > */ >- if (state->timeout == 0) { >+ expired = timeval_expired(&state->endtime); >+ if (expired) { > status = state->deny_status; > tevent_req_nterror(req, status); > goto done; >@@ -278,7 +288,6 @@ struct tevent_req *smbd_smb1_do_locks_send( > TALLOC_FREE(lck); > tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); > >- state->endtime = timeval_current_ofs_msec(state->timeout); > endtime = state->endtime; > > if (blocking_smblctx == UINT64_MAX) { >@@ -363,13 +372,13 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > struct smbd_smb1_do_locks_state *retry_state = tevent_req_data( > retry_req, struct smbd_smb1_do_locks_state); > struct share_mode_lock *lck; >- struct timeval endtime; >+ struct timeval endtime = { 0 }; > struct server_id blocking_pid = { 0 }; > uint64_t blocking_smblctx = 0; > struct tevent_req *subreq = NULL; > NTSTATUS status; > bool ok; >- double elapsed; >+ bool expired; > > lck = get_existing_share_mode_lock(state, fsp->file_id); > if (tevent_req_nomem(lck, req)) { >@@ -393,7 +402,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > } > > /* >- * The client specified timeout elapsed >+ * The client specified timeout expired > * avoid further retries. > * > * Otherwise keep waiting either waiting >@@ -406,8 +415,8 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > * NT_STATUS_FILE_LOCK_CONFLICT > * instead of NT_STATUS_LOCK_NOT_GRANTED. > */ >- elapsed = timeval_elapsed(&state->endtime); >- if (elapsed > 0) { >+ expired = timeval_expired(&state->endtime); >+ if (expired) { > status = state->deny_status; > goto done; > } >-- >2.17.1 > > >From f479c7bc03a06a409b0037d7957806ba3208b55b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 18:02:57 +0200 >Subject: [PATCH 168/376] s3:blocking: split out > smbd_smb1_do_locks_setup_timeout() > >This function can be called multiple times, but only >the first time will setup the endtime. And the >endtime is relative to the request time and not >the current time. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8da7c10a58292022ee57406db9a365de9ffaf5cf) >--- > source3/smbd/blocking.c | 98 ++++++++++++++++++++++++++--------------- > 1 file changed, 63 insertions(+), 35 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 9f64a86d3ee..98074c0c09a 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -117,6 +117,68 @@ static void smbd_smb1_do_locks_retry(struct tevent_req *subreq); > static void smbd_smb1_blocked_locks_cleanup( > struct tevent_req *req, enum tevent_req_state req_state); > >+static void smbd_smb1_do_locks_setup_timeout( >+ struct smbd_smb1_do_locks_state *state, >+ const struct smbd_lock_element *blocker) >+{ >+ struct files_struct *fsp = state->fsp; >+ >+ if (!timeval_is_zero(&state->endtime)) { >+ /* >+ * already done >+ */ >+ return; >+ } >+ >+ if ((state->timeout != 0) && (state->timeout != UINT32_MAX)) { >+ /* >+ * Windows internal resolution for blocking locks >+ * seems to be about 200ms... Don't wait for less than >+ * that. JRA. >+ */ >+ state->timeout = MAX(state->timeout, lp_lock_spin_time()); >+ } >+ >+ if (state->timeout != 0) { >+ goto set_endtime; >+ } >+ >+ if (blocker == NULL) { >+ goto set_endtime; >+ } >+ >+ if ((blocker->offset >= 0xEF000000) && >+ ((blocker->offset >> 63) == 0)) { >+ /* >+ * This must be an optimization of an ancient >+ * application bug... >+ */ >+ state->timeout = lp_lock_spin_time(); >+ } >+ >+ if ((fsp->lock_failure_seen) && >+ (blocker->offset == fsp->lock_failure_offset)) { >+ /* >+ * Delay repeated lock attempts on the same >+ * lock. Maybe a more advanced version of the >+ * above check? >+ */ >+ DBG_DEBUG("Delaying lock request due to previous " >+ "failure\n"); >+ state->timeout = lp_lock_spin_time(); >+ } >+ >+set_endtime: >+ /* >+ * Note state->timeout might still 0, >+ * but that's ok, as we don't want to retry >+ * in that case. >+ */ >+ state->endtime = timeval_add(&state->smbreq->request_time, >+ state->timeout / 1000, >+ (state->timeout % 1000) * 1000); >+} >+ > static void smbd_smb1_do_locks_update_polling_msecs( > struct smbd_smb1_do_locks_state *state) > { >@@ -196,15 +258,6 @@ struct tevent_req *smbd_smb1_do_locks_send( > return tevent_req_post(req, ev); > } > >- if ((state->timeout != 0) && (state->timeout != UINT32_MAX)) { >- /* >- * Windows internal resolution for blocking locks >- * seems to be about 200ms... Don't wait for less than >- * that. JRA. >- */ >- state->timeout = MAX(state->timeout, lp_lock_spin_time()); >- } >- > lck = get_existing_share_mode_lock(state, state->fsp->file_id); > if (tevent_req_nomem(lck, req)) { > DBG_DEBUG("Could not get share mode lock\n"); >@@ -228,32 +281,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > goto done; > } > >- if (state->timeout == 0) { >- struct smbd_lock_element *blocker = &locks[state->blocker]; >- >- if ((blocker->offset >= 0xEF000000) && >- ((blocker->offset >> 63) == 0)) { >- /* >- * This must be an optimization of an ancient >- * application bug... >- */ >- state->timeout = lp_lock_spin_time(); >- } >- >- if ((fsp->lock_failure_seen) && >- (blocker->offset == fsp->lock_failure_offset)) { >- /* >- * Delay repeated lock attempts on the same >- * lock. Maybe a more advanced version of the >- * above check? >- */ >- DBG_DEBUG("Delaying lock request due to previous " >- "failure\n"); >- state->timeout = lp_lock_spin_time(); >- } >- } >- state->endtime = timeval_current_ofs_msec(state->timeout); >- >+ smbd_smb1_do_locks_setup_timeout(state, &locks[state->blocker]); > DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", > state->timeout, > blocking_smblctx); >-- >2.17.1 > > >From 333026209a8abe5d9d00297ce7f0d6cdf66d6ce0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 15:21:50 +0200 >Subject: [PATCH 169/376] s3:blocking: do the timeout calculation before > calling dbwrap_watched_watch_send() > >This makes the next commits easier to understand. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 997548a5f1a14d82f1e80cce6d9ee55e85b5107c) >--- > source3/smbd/blocking.c | 32 ++++++++++++++++---------------- > 1 file changed, 16 insertions(+), 16 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 98074c0c09a..ac90f8c3ef1 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -308,14 +308,6 @@ struct tevent_req *smbd_smb1_do_locks_send( > } > state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; > >- subreq = dbwrap_watched_watch_send( >- state, state->ev, lck->data->record, blocking_pid); >- if (tevent_req_nomem(subreq, req)) { >- goto done; >- } >- TALLOC_FREE(lck); >- tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); >- > endtime = state->endtime; > > if (blocking_smblctx == UINT64_MAX) { >@@ -330,6 +322,14 @@ struct tevent_req *smbd_smb1_do_locks_send( > endtime = timeval_min(&endtime, &tmp); > } > >+ subreq = dbwrap_watched_watch_send( >+ state, state->ev, lck->data->record, blocking_pid); >+ if (tevent_req_nomem(subreq, req)) { >+ goto done; >+ } >+ TALLOC_FREE(lck); >+ tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); >+ > ok = tevent_req_set_endtime(subreq, state->ev, endtime); > if (!ok) { > tevent_req_oom(req); >@@ -450,14 +450,6 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > } > state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; > >- subreq = dbwrap_watched_watch_send( >- state, state->ev, lck->data->record, blocking_pid); >- if (tevent_req_nomem(subreq, req)) { >- goto done; >- } >- TALLOC_FREE(lck); >- tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); >- > endtime = state->endtime; > > if (blocking_smblctx == UINT64_MAX) { >@@ -472,6 +464,14 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > endtime = timeval_min(&endtime, &tmp); > } > >+ subreq = dbwrap_watched_watch_send( >+ state, state->ev, lck->data->record, blocking_pid); >+ if (tevent_req_nomem(subreq, req)) { >+ goto done; >+ } >+ TALLOC_FREE(lck); >+ tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); >+ > ok = tevent_req_set_endtime(subreq, state->ev, endtime); > if (!ok) { > status = NT_STATUS_NO_MEMORY; >-- >2.17.1 > > >From 11e489b0789d7c9cc7f082c054c97c6c4c6f131a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 16 Aug 2019 14:55:13 +0200 >Subject: [PATCH 170/376] s3:blocking: fix the fsp->blocked_smb1_lock_reqs > handling > >A new request is first checks against all pending >requests before checking the already granted locks. > >Before we retried the lock array of another request >(the first in the list), but then finished current request, >which is wrong. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 312327106271abafeb53e62dfb71a38bf93e2d41) >--- > selftest/knownfail.d/multilock | 4 - > source3/smbd/blocking.c | 134 ++++++++++++++++++++++++++++++--- > 2 files changed, 125 insertions(+), 13 deletions(-) > delete mode 100644 selftest/knownfail.d/multilock > >diff --git a/selftest/knownfail.d/multilock b/selftest/knownfail.d/multilock >deleted file mode 100644 >index 9fa497bd643..00000000000 >--- a/selftest/knownfail.d/multilock >+++ /dev/null >@@ -1,4 +0,0 @@ >-^samba3.raw.lock.multilock3.*nt4_dc >-^samba3.raw.lock.multilock4.*nt4_dc >-^samba3.raw.lock.multilock5.*nt4_dc >-^samba3.raw.lock.multilock6.*nt4_dc >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index ac90f8c3ef1..39042d2f46d 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -116,6 +116,14 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req); > static void smbd_smb1_do_locks_retry(struct tevent_req *subreq); > static void smbd_smb1_blocked_locks_cleanup( > struct tevent_req *req, enum tevent_req_state req_state); >+static NTSTATUS smbd_smb1_do_locks_check( >+ struct files_struct *fsp, >+ enum brl_flavour lock_flav, >+ uint16_t num_locks, >+ struct smbd_lock_element *locks, >+ uint16_t *blocker_idx, >+ struct server_id *blocking_pid, >+ uint64_t *blocking_smblctx); > > static void smbd_smb1_do_locks_setup_timeout( > struct smbd_smb1_do_locks_state *state, >@@ -264,7 +272,7 @@ struct tevent_req *smbd_smb1_do_locks_send( > return tevent_req_post(req, ev); > } > >- status = smbd_do_locks_try( >+ status = smbd_smb1_do_locks_check( > state->fsp, > state->lock_flav, > state->num_locks, >@@ -390,15 +398,123 @@ static void smbd_smb1_blocked_locks_cleanup( > fsp, blocked, struct tevent_req *, num_blocked-1); > } > >+static NTSTATUS smbd_smb1_do_locks_check_blocked( >+ uint16_t num_blocked, >+ struct smbd_lock_element *blocked, >+ uint16_t num_locks, >+ struct smbd_lock_element *locks, >+ uint16_t *blocker_idx, >+ uint64_t *blocking_smblctx) >+{ >+ uint16_t li; >+ >+ for (li=0; li < num_locks; li++) { >+ struct smbd_lock_element *l = &locks[li]; >+ uint16_t bi; >+ bool valid; >+ >+ valid = byte_range_valid(l->offset, l->count); >+ if (!valid) { >+ return NT_STATUS_INVALID_LOCK_RANGE; >+ } >+ >+ for (bi = 0; bi < num_blocked; bi++) { >+ struct smbd_lock_element *b = &blocked[li]; >+ bool overlap; >+ >+ /* Read locks never conflict. */ >+ if (l->brltype == READ_LOCK && b->brltype == READ_LOCK) { >+ continue; >+ } >+ >+ overlap = byte_range_overlap(l->offset, >+ l->count, >+ b->offset, >+ b->count); >+ if (!overlap) { >+ continue; >+ } >+ >+ *blocker_idx = li; >+ *blocking_smblctx = b->smblctx; >+ return NT_STATUS_LOCK_NOT_GRANTED; >+ } >+ } >+ >+ return NT_STATUS_OK; >+} >+ >+static NTSTATUS smbd_smb1_do_locks_check( >+ struct files_struct *fsp, >+ enum brl_flavour lock_flav, >+ uint16_t num_locks, >+ struct smbd_lock_element *locks, >+ uint16_t *blocker_idx, >+ struct server_id *blocking_pid, >+ uint64_t *blocking_smblctx) >+{ >+ struct tevent_req **blocked = fsp->blocked_smb1_lock_reqs; >+ size_t num_blocked = talloc_array_length(blocked); >+ NTSTATUS status; >+ size_t bi; >+ >+ /* >+ * We check the pending/blocked requests >+ * from the oldest to the youngest request. >+ * >+ * Note due to the retry logic the current request >+ * might already be in the list. >+ */ >+ >+ for (bi = 0; bi < num_blocked; bi++) { >+ struct smbd_smb1_do_locks_state *blocked_state = >+ tevent_req_data(blocked[bi], >+ struct smbd_smb1_do_locks_state); >+ >+ if (blocked_state->locks == locks) { >+ SMB_ASSERT(blocked_state->num_locks == num_locks); >+ SMB_ASSERT(blocked_state->lock_flav == lock_flav); >+ >+ /* >+ * We found ourself... >+ */ >+ break; >+ } >+ >+ status = smbd_smb1_do_locks_check_blocked( >+ blocked_state->num_locks, >+ blocked_state->locks, >+ num_locks, >+ locks, >+ blocker_idx, >+ blocking_smblctx); >+ if (!NT_STATUS_IS_OK(status)) { >+ *blocking_pid = messaging_server_id( >+ fsp->conn->sconn->msg_ctx); >+ return status; >+ } >+ } >+ >+ status = smbd_do_locks_try( >+ fsp, >+ lock_flav, >+ num_locks, >+ locks, >+ blocker_idx, >+ blocking_pid, >+ blocking_smblctx); >+ if (!NT_STATUS_IS_OK(status)) { >+ return status; >+ } >+ >+ return NT_STATUS_OK; >+} >+ > static void smbd_smb1_do_locks_try(struct tevent_req *req) > { > struct smbd_smb1_do_locks_state *state = tevent_req_data( > req, struct smbd_smb1_do_locks_state); > struct files_struct *fsp = state->fsp; >- struct tevent_req **blocked = fsp->blocked_smb1_lock_reqs; >- struct tevent_req *retry_req = blocked[0]; >- struct smbd_smb1_do_locks_state *retry_state = tevent_req_data( >- retry_req, struct smbd_smb1_do_locks_state); > struct share_mode_lock *lck; > struct timeval endtime = { 0 }; > struct server_id blocking_pid = { 0 }; >@@ -414,11 +530,11 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > return; > } > >- status = smbd_do_locks_try( >+ status = smbd_smb1_do_locks_check( > fsp, >- retry_state->lock_flav, >- retry_state->num_locks, >- retry_state->locks, >+ state->lock_flav, >+ state->num_locks, >+ state->locks, > &state->blocker, > &blocking_pid, > &blocking_smblctx); >-- >2.17.1 > > >From 5e9d294a045d7b7e1d77dd5f306d74b165585344 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 18:18:50 +0200 >Subject: [PATCH 171/376] s3:blocking: call smbd_smb1_do_locks_setup_timeout() > also in smbd_smb1_do_locks_try() > >This is a noop if smbd_smb1_do_locks_setup_timeout() was called before. > >But it allows us to use smbd_smb1_do_locks_try() in >smbd_smb1_do_locks_send() in a following commit. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 6e30a89b3f00ad55391454fbaa1272074e1962f0) >--- > source3/smbd/blocking.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 39042d2f46d..77dfc5a3d44 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -545,6 +545,11 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > goto done; > } > >+ smbd_smb1_do_locks_setup_timeout(state, &state->locks[state->blocker]); >+ DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", >+ state->timeout, >+ blocking_smblctx); >+ > /* > * The client specified timeout expired > * avoid further retries. >-- >2.17.1 > > >From c8086b8873b37fde75dfbcd0054b5db7565b8708 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Aug 2019 20:09:55 +0200 >Subject: [PATCH 172/376] s3:blocking: make use of smbd_smb1_do_locks_try() in > smbd_smb1_do_locks_send() > >We only need the logic to call smbd_smb1_do_locks_check() and a possible >retry once in smbd_smb1_do_locks_try(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8975673e3c3f9f7dbdb7ba7562bb81a62cd24e2e) >--- > source3/smbd/blocking.c | 90 ++--------------------------------------- > 1 file changed, 4 insertions(+), 86 deletions(-) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 77dfc5a3d44..514985bcd75 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -224,15 +224,9 @@ struct tevent_req *smbd_smb1_do_locks_send( > uint16_t num_locks, > struct smbd_lock_element *locks) > { >- struct tevent_req *req = NULL, *subreq = NULL; >+ struct tevent_req *req = NULL; > struct smbd_smb1_do_locks_state *state = NULL; >- struct share_mode_lock *lck = NULL; >- struct server_id blocking_pid = { 0 }; >- uint64_t blocking_smblctx = 0; >- struct timeval endtime = { 0 }; >- NTSTATUS status = NT_STATUS_OK; > bool ok; >- bool expired; > > req = tevent_req_create( > mem_ctx, &state, struct smbd_smb1_do_locks_state); >@@ -266,94 +260,18 @@ struct tevent_req *smbd_smb1_do_locks_send( > return tevent_req_post(req, ev); > } > >- lck = get_existing_share_mode_lock(state, state->fsp->file_id); >- if (tevent_req_nomem(lck, req)) { >- DBG_DEBUG("Could not get share mode lock\n"); >+ smbd_smb1_do_locks_try(req); >+ if (!tevent_req_is_in_progress(req)) { > return tevent_req_post(req, ev); > } > >- status = smbd_smb1_do_locks_check( >- state->fsp, >- state->lock_flav, >- state->num_locks, >- state->locks, >- &state->blocker, >- &blocking_pid, >- &blocking_smblctx); >- if (NT_STATUS_IS_OK(status)) { >- tevent_req_done(req); >- goto done; >- } >- if (!ERROR_WAS_LOCK_DENIED(status)) { >- tevent_req_nterror(req, status); >- goto done; >- } >- >- smbd_smb1_do_locks_setup_timeout(state, &locks[state->blocker]); >- DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", >- state->timeout, >- blocking_smblctx); >- >- /* >- * The client specified timeout expired >- * avoid further retries. >- * >- * Otherwise keep waiting either waiting >- * for changes in locking.tdb or the polling >- * mode timers waiting for posix locks. >- * >- * If the endtime is not elapsed yet, >- * it means we'll retry after a timeout. >- * In that case we'll have to return >- * NT_STATUS_FILE_LOCK_CONFLICT >- * instead of NT_STATUS_LOCK_NOT_GRANTED. >- */ >- expired = timeval_expired(&state->endtime); >- if (expired) { >- status = state->deny_status; >- tevent_req_nterror(req, status); >- goto done; >- } >- state->deny_status = NT_STATUS_FILE_LOCK_CONFLICT; >- >- endtime = state->endtime; >- >- if (blocking_smblctx == UINT64_MAX) { >- struct timeval tmp; >- >- smbd_smb1_do_locks_update_polling_msecs(state); >- >- DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", >- state->polling_msecs); >- >- tmp = timeval_current_ofs_msec(state->polling_msecs); >- endtime = timeval_min(&endtime, &tmp); >- } >- >- subreq = dbwrap_watched_watch_send( >- state, state->ev, lck->data->record, blocking_pid); >- if (tevent_req_nomem(subreq, req)) { >- goto done; >- } >- TALLOC_FREE(lck); >- tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); >- >- ok = tevent_req_set_endtime(subreq, state->ev, endtime); >- if (!ok) { >- tevent_req_oom(req); >- goto done; >- } >- > ok = smbd_smb1_fsp_add_blocked_lock_req(fsp, req); > if (!ok) { > tevent_req_oom(req); >- goto done; >+ return tevent_req_post(req, ev); > } > tevent_req_set_cleanup_fn(req, smbd_smb1_blocked_locks_cleanup); > return req; >-done: >- TALLOC_FREE(lck); >- return tevent_req_post(req, ev); > } > > static void smbd_smb1_blocked_locks_cleanup( >-- >2.17.1 > > >From a1117587afb6bf2f813982dfca4a47e982f44b96 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 15:29:32 +0200 >Subject: [PATCH 173/376] s3:blocking: handle NT_STATUS_RETRY from the VFS > backend > >This allows the VFS backends to implement async byte >range locking. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7d1cd6f22e7e3d95aba04c45776057945c2a5e30) >--- > source3/smbd/blocking.c | 84 +++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 84 insertions(+) > >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index 514985bcd75..fbd1ea812f3 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -103,6 +103,7 @@ struct smbd_smb1_do_locks_state { > struct files_struct *fsp; > uint32_t timeout; > uint32_t polling_msecs; >+ uint32_t retry_msecs; > struct timeval endtime; > bool large_offset; /* required for correct cancel */ > enum brl_flavour lock_flav; >@@ -187,6 +188,33 @@ set_endtime: > (state->timeout % 1000) * 1000); > } > >+static void smbd_smb1_do_locks_update_retry_msecs( >+ struct smbd_smb1_do_locks_state *state) >+{ >+ /* >+ * The default lp_lock_spin_time() is 200ms, >+ * we just use half of it to trigger the first retry. >+ * >+ * v_min is in the range of 0.001 to 10 secs >+ * (0.1 secs by default) >+ * >+ * v_max is in the range of 0.01 to 100 secs >+ * (1.0 secs by default) >+ * >+ * The typical steps are: >+ * 0.1, 0.2, 0.3, 0.4, ... 1.0 >+ */ >+ uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time()))/2; >+ uint32_t v_max = 10 * v_min; >+ >+ if (state->retry_msecs >= v_max) { >+ state->retry_msecs = v_max; >+ return; >+ } >+ >+ state->retry_msecs += v_min; >+} >+ > static void smbd_smb1_do_locks_update_polling_msecs( > struct smbd_smb1_do_locks_state *state) > { >@@ -459,9 +487,60 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > if (NT_STATUS_IS_OK(status)) { > goto done; > } >+ if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { >+ /* >+ * We got NT_STATUS_RETRY, >+ * we reset polling_msecs so that >+ * that the retries based on LOCK_NOT_GRANTED >+ * will later start with small intervalls again. >+ */ >+ state->polling_msecs = 0; >+ >+ /* >+ * The backend wasn't able to decide yet. >+ * We need to wait even for non-blocking >+ * locks. >+ * >+ * The backend uses blocking_smblctx == UINT64_MAX >+ * to indicate that we should use retry timers. >+ * >+ * It uses blocking_smblctx == 0 to indicate >+ * it will use share_mode_wakeup_waiters() >+ * to wake us. Note that unrelated changes in >+ * locking.tdb may cause retries. >+ */ >+ >+ if (blocking_smblctx != UINT64_MAX) { >+ SMB_ASSERT(blocking_smblctx == 0); >+ goto setup_retry; >+ } >+ >+ smbd_smb1_do_locks_update_retry_msecs(state); >+ >+ DBG_DEBUG("Waiting for a backend decision. " >+ "Retry in %"PRIu32" msecs\n", >+ state->retry_msecs); >+ >+ /* >+ * We completely ignore state->endtime here >+ * we we'll wait for a backend decision forever. >+ * If the backend is smart enough to implement >+ * some NT_STATUS_RETRY logic, it has to >+ * switch to any other status after in order >+ * to avoid waiting forever. >+ */ >+ endtime = timeval_current_ofs_msec(state->retry_msecs); >+ goto setup_retry; >+ } > if (!ERROR_WAS_LOCK_DENIED(status)) { > goto done; > } >+ /* >+ * We got LOCK_NOT_GRANTED, make sure >+ * a following STATUS_RETRY will start >+ * with short intervalls again. >+ */ >+ state->retry_msecs = 0; > > smbd_smb1_do_locks_setup_timeout(state, &state->locks[state->blocker]); > DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", >@@ -503,6 +582,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > endtime = timeval_min(&endtime, &tmp); > } > >+setup_retry: > subreq = dbwrap_watched_watch_send( > state, state->ev, lck->data->record, blocking_pid); > if (tevent_req_nomem(subreq, req)) { >@@ -511,6 +591,10 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) > TALLOC_FREE(lck); > tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); > >+ if (timeval_is_zero(&endtime)) { >+ return; >+ } >+ > ok = tevent_req_set_endtime(subreq, state->ev, endtime); > if (!ok) { > status = NT_STATUS_NO_MEMORY; >-- >2.17.1 > > >From 74527a20584bd9d22c8487a6ebdeaca21525afe3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 16:25:59 +0200 >Subject: [PATCH 174/376] s3:smb2_lock: handle NT_STATUS_RETRY from the VFS > backend > >This allows the VFS backends to implement async byte >range locking. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7471b0f63276e707784c98b832992ff08b1898ef) >--- > source3/smbd/smb2_lock.c | 80 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 80 insertions(+) > >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 8ba54fe6995..26de8b521ed 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -44,6 +44,7 @@ struct smbd_smb2_lock_state { > struct files_struct *fsp; > bool blocking; > uint32_t polling_msecs; >+ uint32_t retry_msecs; > uint16_t lock_count; > struct smbd_lock_element *locks; > }; >@@ -372,6 +373,33 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return req; > } > >+static void smbd_smb2_lock_update_retry_msecs( >+ struct smbd_smb2_lock_state *state) >+{ >+ /* >+ * The default lp_lock_spin_time() is 200ms, >+ * we just use half of it to trigger the first retry. >+ * >+ * v_min is in the range of 0.001 to 10 secs >+ * (0.1 secs by default) >+ * >+ * v_max is in the range of 0.01 to 100 secs >+ * (1.0 secs by default) >+ * >+ * The typical steps are: >+ * 0.1, 0.2, 0.3, 0.4, ... 1.0 >+ */ >+ uint32_t v_min = MAX(2, MIN(20000, lp_lock_spin_time()))/2; >+ uint32_t v_max = 10 * v_min; >+ >+ if (state->retry_msecs >= v_max) { >+ state->retry_msecs = v_max; >+ return; >+ } >+ >+ state->retry_msecs += v_min; >+} >+ > static void smbd_smb2_lock_update_polling_msecs( > struct smbd_smb2_lock_state *state) > { >@@ -429,6 +457,51 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > tevent_req_done(req); > return; > } >+ if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { >+ /* >+ * We got NT_STATUS_RETRY, >+ * we reset polling_msecs so that >+ * that the retries based on LOCK_NOT_GRANTED >+ * will later start with small intervalls again. >+ */ >+ state->polling_msecs = 0; >+ >+ /* >+ * The backend wasn't able to decide yet. >+ * We need to wait even for non-blocking >+ * locks. >+ * >+ * The backend uses blocking_smblctx == UINT64_MAX >+ * to indicate that we should use retry timers. >+ * >+ * It uses blocking_smblctx == 0 to indicate >+ * it will use share_mode_wakeup_waiters() >+ * to wake us. Note that unrelated changes in >+ * locking.tdb may cause retries. >+ */ >+ >+ if (blocking_smblctx != UINT64_MAX) { >+ SMB_ASSERT(blocking_smblctx == 0); >+ goto setup_retry; >+ } >+ >+ smbd_smb2_lock_update_retry_msecs(state); >+ >+ DBG_DEBUG("Waiting for a backend decision. " >+ "Retry in %"PRIu32" msecs\n", >+ state->retry_msecs); >+ >+ /* >+ * We completely ignore state->endtime here >+ * we we'll wait for a backend decision forever. >+ * If the backend is smart enough to implement >+ * some NT_STATUS_RETRY logic, it has to >+ * switch to any other status after in order >+ * to avoid waiting forever. >+ */ >+ endtime = timeval_current_ofs_msec(state->retry_msecs); >+ goto setup_retry; >+ } > if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { > /* > * This is a bug and will be changed into an assert >@@ -447,6 +520,12 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > tevent_req_nterror(req, status); > return; > } >+ /* >+ * We got LOCK_NOT_GRANTED, make sure >+ * a following STATUS_RETRY will start >+ * with short intervalls again. >+ */ >+ state->retry_msecs = 0; > > if (!state->blocking) { > TALLOC_FREE(lck); >@@ -463,6 +542,7 @@ static void smbd_smb2_lock_try(struct tevent_req *req) > endtime = timeval_current_ofs_msec(state->polling_msecs); > } > >+setup_retry: > DBG_DEBUG("Watching share mode lock\n"); > > subreq = dbwrap_watched_watch_send( >-- >2.17.1 > > >From ec21e68912d2c9b1f4c3aa57d9b34db038a6b66c Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 8 Aug 2019 19:26:28 +0200 >Subject: [PATCH 175/376] s3:locking: add brl_req_guid() and brl_req_mem_ctx() > helper functions > >This allows the vfs backend to detect a retry and keep state between >the retries. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 66d92f37c3a643d97489a59bb6d1e75e91528c20) >--- > source3/include/locking.h | 2 ++ > source3/locking/brlock.c | 45 +++++++++++++++++++++++++++++++++---- > source3/locking/locking.c | 11 ++++++++- > source3/locking/proto.h | 8 +++++++ > source3/modules/vfs_fruit.c | 13 +++++++++++ > source3/smbd/blocking.c | 2 ++ > source3/smbd/globals.c | 18 +++++++++++++++ > source3/smbd/globals.h | 2 ++ > source3/smbd/reply.c | 7 ++++++ > source3/smbd/smb2_lock.c | 1 + > source3/smbd/trans2.c | 2 ++ > 11 files changed, 106 insertions(+), 5 deletions(-) > >diff --git a/source3/include/locking.h b/source3/include/locking.h >index 3e7560bef9e..0175db2dd47 100644 >--- a/source3/include/locking.h >+++ b/source3/include/locking.h >@@ -30,6 +30,7 @@ enum brl_type {READ_LOCK, WRITE_LOCK, UNLOCK_LOCK}; > enum brl_flavour {WINDOWS_LOCK = 0, POSIX_LOCK = 1}; > > #include "librpc/gen_ndr/server_id.h" >+#include "librpc/gen_ndr/misc.h" > > /* This contains elements that differentiate locks. The smbpid is a > client supplied pid, and is essentially the locking context for >@@ -62,6 +63,7 @@ struct lock_struct { > }; > > struct smbd_lock_element { >+ struct GUID req_guid; > uint64_t smblctx; > enum brl_type brltype; > uint64_t offset; >diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c >index 0a85bd0b057..f22580164f9 100644 >--- a/source3/locking/brlock.c >+++ b/source3/locking/brlock.c >@@ -46,6 +46,8 @@ static struct db_context *brlock_db; > > struct byte_range_lock { > struct files_struct *fsp; >+ TALLOC_CTX *req_mem_ctx; >+ const struct GUID *req_guid; > unsigned int num_locks; > bool modified; > struct lock_struct *lock_data; >@@ -84,6 +86,25 @@ struct files_struct *brl_fsp(struct byte_range_lock *brl) > return brl->fsp; > } > >+TALLOC_CTX *brl_req_mem_ctx(const struct byte_range_lock *brl) >+{ >+ if (brl->req_mem_ctx == NULL) { >+ return talloc_get_type_abort(brl, struct byte_range_lock); >+ } >+ >+ return brl->req_mem_ctx; >+} >+ >+const struct GUID *brl_req_guid(const struct byte_range_lock *brl) >+{ >+ if (brl->req_guid == NULL) { >+ static const struct GUID brl_zero_req_guid; >+ return &brl_zero_req_guid; >+ } >+ >+ return brl->req_guid; >+} >+ > /**************************************************************************** > See if two locking contexts are equal. > ****************************************************************************/ >@@ -1823,6 +1844,25 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, files_struct *fsp) > return br_lck; > } > >+struct byte_range_lock *brl_get_locks_for_locking(TALLOC_CTX *mem_ctx, >+ files_struct *fsp, >+ TALLOC_CTX *req_mem_ctx, >+ const struct GUID *req_guid) >+{ >+ struct byte_range_lock *br_lck = NULL; >+ >+ br_lck = brl_get_locks(mem_ctx, fsp); >+ if (br_lck == NULL) { >+ return NULL; >+ } >+ SMB_ASSERT(req_mem_ctx != NULL); >+ br_lck->req_mem_ctx = req_mem_ctx; >+ SMB_ASSERT(req_guid != NULL); >+ br_lck->req_guid = req_guid; >+ >+ return br_lck; >+} >+ > struct brl_get_locks_readonly_state { > TALLOC_CTX *mem_ctx; > struct byte_range_lock **br_lock; >@@ -1884,14 +1924,11 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) > /* > * No locks on this file. Return an empty br_lock. > */ >- br_lock = talloc(fsp, struct byte_range_lock); >+ br_lock = talloc_zero(fsp, struct byte_range_lock); > if (br_lock == NULL) { > return NULL; > } > >- br_lock->num_locks = 0; >- br_lock->lock_data = NULL; >- > } else if (!NT_STATUS_IS_OK(status)) { > DEBUG(3, ("Could not parse byte range lock record: " > "%s\n", nt_errstr(status))); >diff --git a/source3/locking/locking.c b/source3/locking/locking.c >index d87a882d14f..8fa1237d6ad 100644 >--- a/source3/locking/locking.c >+++ b/source3/locking/locking.c >@@ -232,6 +232,8 @@ static void decrement_current_lock_count(files_struct *fsp, > > struct do_lock_state { > struct files_struct *fsp; >+ TALLOC_CTX *req_mem_ctx; >+ const struct GUID *req_guid; > uint64_t smblctx; > uint64_t count; > uint64_t offset; >@@ -251,7 +253,10 @@ static void do_lock_fn( > struct do_lock_state *state = private_data; > struct byte_range_lock *br_lck = NULL; > >- br_lck = brl_get_locks(talloc_tos(), state->fsp); >+ br_lck = brl_get_locks_for_locking(talloc_tos(), >+ state->fsp, >+ state->req_mem_ctx, >+ state->req_guid); > if (br_lck == NULL) { > state->status = NT_STATUS_NO_MEMORY; > return; >@@ -272,6 +277,8 @@ static void do_lock_fn( > } > > NTSTATUS do_lock(files_struct *fsp, >+ TALLOC_CTX *req_mem_ctx, >+ const struct GUID *req_guid, > uint64_t smblctx, > uint64_t count, > uint64_t offset, >@@ -282,6 +289,8 @@ NTSTATUS do_lock(files_struct *fsp, > { > struct do_lock_state state = { > .fsp = fsp, >+ .req_mem_ctx = req_mem_ctx, >+ .req_guid = req_guid, > .smblctx = smblctx, > .count = count, > .offset = offset, >diff --git a/source3/locking/proto.h b/source3/locking/proto.h >index 7cb8bf3e3c9..7cf681561bc 100644 >--- a/source3/locking/proto.h >+++ b/source3/locking/proto.h >@@ -30,6 +30,8 @@ void brl_shutdown(void); > > unsigned int brl_num_locks(const struct byte_range_lock *brl); > struct files_struct *brl_fsp(struct byte_range_lock *brl); >+TALLOC_CTX *brl_req_mem_ctx(const struct byte_range_lock *brl); >+const struct GUID *brl_req_guid(const struct byte_range_lock *brl); > > bool byte_range_valid(uint64_t ofs, uint64_t len); > bool byte_range_overlap(uint64_t ofs1, >@@ -76,6 +78,10 @@ int brl_forall(void (*fn)(struct file_id id, struct server_id pid, > br_off start, br_off size, > void *private_data), > void *private_data); >+struct byte_range_lock *brl_get_locks_for_locking(TALLOC_CTX *mem_ctx, >+ files_struct *fsp, >+ TALLOC_CTX *req_mem_ctx, >+ const struct GUID *req_guid); > struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, > files_struct *fsp); > struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp); >@@ -100,6 +106,8 @@ NTSTATUS query_lock(files_struct *fsp, > enum brl_type *plock_type, > enum brl_flavour lock_flav); > NTSTATUS do_lock(files_struct *fsp, >+ TALLOC_CTX *req_mem_ctx, >+ const struct GUID *req_guid, > uint64_t smblctx, > uint64_t count, > uint64_t offset, >diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c >index 0be7f20e9af..85c7af21d58 100644 >--- a/source3/modules/vfs_fruit.c >+++ b/source3/modules/vfs_fruit.c >@@ -2621,6 +2621,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > bool netatalk_already_open_for_writing = false; > bool netatalk_already_open_with_deny_read = false; > bool netatalk_already_open_with_deny_write = false; >+ struct GUID req_guid = GUID_random(); > > /* FIXME: hardcoded data fork, add resource fork */ > enum apple_fork fork_type = APPLE_FORK_DATA; >@@ -2684,8 +2685,11 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > /* Set NetAtalk locks matching our access */ > if (access_mask & FILE_READ_DATA) { > off = access_to_netatalk_brl(fork_type, FILE_READ_DATA); >+ req_guid.time_hi_and_version = __LINE__; > status = do_lock( > fsp, >+ talloc_tos(), >+ &req_guid, > fsp->op->global->open_persistent_id, > 1, > off, >@@ -2701,8 +2705,11 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > > if (!share_for_read) { > off = denymode_to_netatalk_brl(fork_type, DENY_READ); >+ req_guid.time_hi_and_version = __LINE__; > status = do_lock( > fsp, >+ talloc_tos(), >+ &req_guid, > fsp->op->global->open_persistent_id, > 1, > off, >@@ -2718,8 +2725,11 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > > if (access_mask & FILE_WRITE_DATA) { > off = access_to_netatalk_brl(fork_type, FILE_WRITE_DATA); >+ req_guid.time_hi_and_version = __LINE__; > status = do_lock( > fsp, >+ talloc_tos(), >+ &req_guid, > fsp->op->global->open_persistent_id, > 1, > off, >@@ -2735,8 +2745,11 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, > > if (!share_for_write) { > off = denymode_to_netatalk_brl(fork_type, DENY_WRITE); >+ req_guid.time_hi_and_version = __LINE__; > status = do_lock( > fsp, >+ talloc_tos(), >+ &req_guid, > fsp->op->global->open_persistent_id, > 1, > off, >diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c >index fbd1ea812f3..94e75a9b405 100644 >--- a/source3/smbd/blocking.c >+++ b/source3/smbd/blocking.c >@@ -45,6 +45,8 @@ NTSTATUS smbd_do_locks_try( > > status = do_lock( > fsp, >+ locks, /* req_mem_ctx */ >+ &e->req_guid, > e->smblctx, > e->count, > e->offset, >diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c >index 6bc448b901d..0cdce20d122 100644 >--- a/source3/smbd/globals.c >+++ b/source3/smbd/globals.c >@@ -109,3 +109,21 @@ void smbd_init_globals(void) > > ZERO_STRUCT(sec_ctx_stack); > } >+ >+struct GUID smbd_request_guid(struct smb_request *smb1req, uint16_t idx) >+{ >+ struct GUID v = { >+ .time_low = (uint32_t)smb1req->mid, >+ .time_hi_and_version = idx, >+ }; >+ >+ if (smb1req->smb2req != NULL) { >+ v.time_mid = (uint16_t)smb1req->smb2req->current_idx; >+ } else { >+ v.time_mid = (uint16_t)(uintptr_t)smb1req->vwv; >+ } >+ >+ SBVAL((uint8_t *)&v, 8, (uintptr_t)smb1req->xconn); >+ >+ return v; >+} >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index 03d50882d16..47916ba29a1 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -115,6 +115,8 @@ DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn); > void smbd_lock_socket(struct smbXsrv_connection *xconn); > void smbd_unlock_socket(struct smbXsrv_connection *xconn); > >+struct GUID smbd_request_guid(struct smb_request *smb1req, uint16_t idx); >+ > NTSTATUS smbd_do_unlocking(struct smb_request *req, > files_struct *fsp, > uint16_t num_ulocks, >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index 2622681a2da..dec67a10cae 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -3842,6 +3842,7 @@ void reply_lockread(struct smb_request *req) > */ > > *lck = (struct smbd_lock_element) { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = req->smbpid, > .brltype = WRITE_LOCK, > .count = SVAL(req->vwv+1, 0), >@@ -4869,6 +4870,7 @@ void reply_writeunlock(struct smb_request *req) > > if (numtowrite && !fsp->print_file) { > struct smbd_lock_element l = { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = req->smbpid, > .brltype = UNLOCK_LOCK, > .offset = startpos, >@@ -5764,6 +5766,7 @@ void reply_lock(struct smb_request *req) > } > > *lck = (struct smbd_lock_element) { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = req->smbpid, > .brltype = WRITE_LOCK, > .count = IVAL(req->vwv+1, 0), >@@ -5855,6 +5858,7 @@ void reply_unlock(struct smb_request *req) > } > > lck = (struct smbd_lock_element) { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = req->smbpid, > .brltype = UNLOCK_LOCK, > .offset = IVAL(req->vwv+3, 0), >@@ -8433,6 +8437,8 @@ void reply_lockingX(struct smb_request *req) > * smb_unlkrng structs > */ > for (i = 0; i < num_ulocks; i++) { >+ ulocks[i].req_guid = smbd_request_guid(req, >+ UINT16_MAX - i), > ulocks[i].smblctx = get_lock_pid( > data, i, large_file_format); > ulocks[i].count = get_lock_count( >@@ -8490,6 +8496,7 @@ void reply_lockingX(struct smb_request *req) > } > > for (i = 0; i < num_locks; i++) { >+ locks[i].req_guid = smbd_request_guid(req, i), > locks[i].smblctx = get_lock_pid(data, i, large_file_format); > locks[i].count = get_lock_count(data, i, large_file_format); > locks[i].offset = get_lock_offset(data, i, large_file_format); >diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c >index 26de8b521ed..381aae6cb60 100644 >--- a/source3/smbd/smb2_lock.c >+++ b/source3/smbd/smb2_lock.c >@@ -318,6 +318,7 @@ static struct tevent_req *smbd_smb2_lock_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >+ locks[i].req_guid = smbd_request_guid(smb2req->smb1req, i); > locks[i].smblctx = fsp->op->global->open_persistent_id; > locks[i].offset = in_locks[i].offset; > locks[i].count = in_locks[i].length; >diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c >index 5b99240e9e8..0539b35bb73 100644 >--- a/source3/smbd/trans2.c >+++ b/source3/smbd/trans2.c >@@ -7572,6 +7572,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, > > if (lock_type == UNLOCK_LOCK) { > struct smbd_lock_element l = { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = smblctx, > .brltype = UNLOCK_LOCK, > .offset = offset, >@@ -7587,6 +7588,7 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn, > } > > *lck = (struct smbd_lock_element) { >+ .req_guid = smbd_request_guid(req, 0), > .smblctx = smblctx, > .brltype = lock_type, > .count = count, >-- >2.17.1 > > >From 9bf1c5c3e48ff905eec6f9ee469f1067b4105d42 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 19 Aug 2019 18:22:38 +0200 >Subject: [PATCH 176/376] vfs_delay_inject: add support for > brl_[un]lock_windows() > >This demonstrates the two ways to handle the retry: >- smb layer retry => plock->context.smblctx = UINT64_MAX >- vfs backend retry => plock->context.smblctx = 0 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit c2503a5c68e967054ab84ca0d8ce693200c2e002) >--- > source3/modules/vfs_delay_inject.c | 117 +++++++++++++++++++++++++++++ > 1 file changed, 117 insertions(+) > >diff --git a/source3/modules/vfs_delay_inject.c b/source3/modules/vfs_delay_inject.c >index d561fadb03b..569bd40054a 100644 >--- a/source3/modules/vfs_delay_inject.c >+++ b/source3/modules/vfs_delay_inject.c >@@ -304,12 +304,129 @@ static ssize_t vfs_delay_inject_pwrite_recv(struct tevent_req *req, > return state->ret; > } > >+struct vfs_delay_inject_brl_lock_state { >+ struct vfs_delay_inject_brl_lock_state *prev, *next; >+ struct files_struct *fsp; >+ struct GUID req_guid; >+ struct timeval delay_tv; >+ struct tevent_timer *delay_te; >+}; >+ >+static struct vfs_delay_inject_brl_lock_state *brl_lock_states; >+ >+static int vfs_delay_inject_brl_lock_state_destructor(struct vfs_delay_inject_brl_lock_state *state) >+{ >+ DLIST_REMOVE(brl_lock_states, state); >+ return 0; >+} >+ >+static void vfs_delay_inject_brl_lock_timer(struct tevent_context *ev, >+ struct tevent_timer *te, >+ struct timeval current_time, >+ void *private_data) >+{ >+ struct vfs_delay_inject_brl_lock_state *state = >+ talloc_get_type_abort(private_data, >+ struct vfs_delay_inject_brl_lock_state); >+ NTSTATUS status; >+ >+ TALLOC_FREE(state->delay_te); >+ >+ status = share_mode_wakeup_waiters(state->fsp->file_id); >+ if (!NT_STATUS_IS_OK(status)) { >+ DBG_ERR("share_mode_wakeup_waiters(%s) %s\n", >+ file_id_string_tos(&state->fsp->file_id), >+ nt_errstr(status)); >+ } >+} >+ >+static NTSTATUS vfs_delay_inject_brl_lock_windows(struct vfs_handle_struct *handle, >+ struct byte_range_lock *br_lck, >+ struct lock_struct *plock) >+{ >+ struct files_struct *fsp = brl_fsp(br_lck); >+ TALLOC_CTX *req_mem_ctx = brl_req_mem_ctx(br_lck); >+ const struct GUID *req_guid = brl_req_guid(br_lck); >+ struct vfs_delay_inject_brl_lock_state *state = NULL; >+ bool expired; >+ >+ for (state = brl_lock_states; state != NULL; state = state->next) { >+ bool match; >+ >+ match = GUID_equal(&state->req_guid, req_guid); >+ if (match) { >+ break; >+ } >+ } >+ >+ if (state == NULL) { >+ int delay; >+ bool use_timer; >+ >+ state = talloc_zero(req_mem_ctx, >+ struct vfs_delay_inject_brl_lock_state); >+ if (state == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ state->fsp = fsp; >+ state->req_guid = *req_guid; >+ >+ delay = lp_parm_int(SNUM(handle->conn), >+ "delay_inject", "brl_lock_windows", 0); >+ state->delay_tv = timeval_current_ofs_msec(delay); >+ >+ use_timer = lp_parm_bool(SNUM(handle->conn), >+ "delay_inject", "brl_lock_windows_use_timer", true); >+ >+ if (use_timer) { >+ state->delay_te = tevent_add_timer( >+ global_event_context(), >+ state, >+ state->delay_tv, >+ vfs_delay_inject_brl_lock_timer, >+ state); >+ if (state->delay_te == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ } >+ >+ talloc_set_destructor(state, >+ vfs_delay_inject_brl_lock_state_destructor); >+ DLIST_ADD_END(brl_lock_states, state); >+ } >+ >+ if (state->delay_te != NULL) { >+ plock->context.smblctx = 0; >+ return NT_STATUS_RETRY; >+ } >+ >+ expired = timeval_expired(&state->delay_tv); >+ if (!expired) { >+ plock->context.smblctx = UINT64_MAX; >+ return NT_STATUS_RETRY; >+ } >+ >+ TALLOC_FREE(state); >+ >+ return SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock); >+} >+ >+static bool vfs_delay_inject_brl_unlock_windows(struct vfs_handle_struct *handle, >+ struct byte_range_lock *br_lck, >+ const struct lock_struct *plock) >+{ >+ return SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, br_lck, plock); >+} >+ > static struct vfs_fn_pointers vfs_delay_inject_fns = { > .ntimes_fn = vfs_delay_inject_ntimes, > .pread_send_fn = vfs_delay_inject_pread_send, > .pread_recv_fn = vfs_delay_inject_pread_recv, > .pwrite_send_fn = vfs_delay_inject_pwrite_send, > .pwrite_recv_fn = vfs_delay_inject_pwrite_recv, >+ >+ .brl_lock_windows_fn = vfs_delay_inject_brl_lock_windows, >+ .brl_unlock_windows_fn = vfs_delay_inject_brl_unlock_windows, > }; > > static_decl_vfs; >-- >2.17.1 > > >From be42cfafee057993d038f7d476d094c53b00b57e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 20 Aug 2019 15:53:59 +0200 >Subject: [PATCH 177/376] s3:selftest: add delay_inject:brl_lock_windows > testing > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14113 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Mon Sep 9 15:42:45 UTC 2019 on sn-devel-184 > >(cherry picked from commit 2b43ce6704ecf035e6734337a2dea3458153a4b2) > >Autobuild-User(v4-11-test): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(v4-11-test): Mon Sep 9 17:19:11 UTC 2019 on sn-devel-184 >--- > selftest/target/Samba3.pm | 12 ++++++++++++ > source3/selftest/tests.py | 4 ++++ > 2 files changed, 16 insertions(+) > >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 9638bb44f08..131d576a767 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -2263,6 +2263,18 @@ sub provision($$$$$$$$$) > delay_inject:pread_send = 2000 > delay_inject:pwrite_send = 2000 > >+[brl_delay_inject1] >+ copy = tmp >+ vfs objects = delay_inject >+ delay_inject:brl_lock_windows = 90 >+ delay_inject:brl_lock_windows_use_timer = yes >+ >+[brl_delay_inject2] >+ copy = tmp >+ vfs objects = delay_inject >+ delay_inject:brl_lock_windows = 90 >+ delay_inject:brl_lock_windows_use_timer = no >+ > [delete_readonly] > path = $prefix_abs/share > delete readonly = yes >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index ebc366de3ea..31cb8ca33f1 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -531,6 +531,10 @@ for t in tests: > plansmbtorture4testsuite(t, env, '//$SERVER/tmp -k no -U$DC_USERNAME@$REALM%$DC_PASSWORD', description='ntlm user@realm') > elif t == "raw.samba3posixtimedlock" or t == "smb2.samba3misc": > plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share') >+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/brl_delay_inject1 -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share', >+ description="brl_delay_inject1") >+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/brl_delay_inject2 -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/nt4_dc/share', >+ description="brl_delay_inject2") > plansmbtorture4testsuite(t, "ad_dc", '//$SERVER_IP/tmpguest -U$USERNAME%$PASSWORD --option=torture:localdir=$SELFTEST_PREFIX/ad_dc/share') > elif t == "raw.chkpath": > plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmpcase -U$USERNAME%$PASSWORD') >-- >2.17.1 > > >From 02ccbe08a53e385460d17b54bbabee5a362e1a5b Mon Sep 17 00:00:00 2001 >From: Evgeny Sinelnikov <sin@altlinux.org> >Date: Wed, 31 Jul 2019 23:17:20 +0400 >Subject: [PATCH 178/376] s3:ldap: Fix join with don't exists machine account >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Add check for requested replies of existing machine object during join >machine to domain. This solves regression fail during join with error: >"None of the information to be translated has been translated." > >https://bugzilla.samba.org/show_bug.cgi?id=14007 > >Reviewed-by: Guenther Deschner <gd@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Günther Deschner <gd@samba.org> >Autobuild-Date(master): Wed Sep 4 17:02:37 UTC 2019 on sn-devel-184 > >(cherry picked from commit ad4ef1657e9b2a088a3bfadcce196cfcceead1dc) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Tue Sep 10 09:13:15 UTC 2019 on sn-devel-184 >--- > source3/libads/ldap.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index 4f3d43b02b1..2110390b65f 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -2121,13 +2121,14 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > } > > ret = ads_find_machine_acct(ads, &res, machine_escaped); >- ads_msgfree(ads, res); >- if (ADS_ERR_OK(ret)) { >+ if (ADS_ERR_OK(ret) && ads_count_replies(ads, res) == 1) { > DBG_DEBUG("Host account for %s already exists.\n", > machine_escaped); > ret = ADS_ERROR_LDAP(LDAP_ALREADY_EXISTS); >+ ads_msgfree(ads, res); > goto done; > } >+ ads_msgfree(ads, res); > > new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_escaped, org_unit); > samAccountName = talloc_asprintf(ctx, "%s$", machine_name); >-- >2.17.1 > > >From 0318b68675d0318027ff5b6abf4a0d010839e6fd Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 30 Aug 2019 14:49:24 +0200 >Subject: [PATCH 179/376] s4:torture: add a file-id related test > >Note I'm using the share vfs_fruit_xattr because I need a share with both a >streams and a acl_* VFS object. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 2ecab3c60abf9baa16a6a5e3eba0fc4720def840) >--- > selftest/knownfail.d/samba3.smb2.create | 1 + > source3/selftest/tests.py | 2 + > source4/selftest/tests.py | 1 + > source4/torture/smb2/create.c | 212 ++++++++++++++++++++++++ > source4/torture/smb2/smb2.c | 1 + > 5 files changed, 217 insertions(+) > create mode 100644 selftest/knownfail.d/samba3.smb2.create > >diff --git a/selftest/knownfail.d/samba3.smb2.create b/selftest/knownfail.d/samba3.smb2.create >new file mode 100644 >index 00000000000..89455dacdf0 >--- /dev/null >+++ b/selftest/knownfail.d/samba3.smb2.create >@@ -0,0 +1 @@ >+^samba3.smb2.fileid.fileid\(nt4_dc\) >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index 31cb8ca33f1..20f2eea7661 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -689,6 +689,8 @@ for t in tests: > plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD') > plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/delete_readonly -U$USERNAME%$PASSWORD --option=torture:delete_readonly=true') > plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD') >+ elif t == "smb2.fileid": >+ plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_xattr -U$USERNAME%$PASSWORD') > elif t == "rpc.wkssvc": > plansmbtorture4testsuite(t, "ad_member", '//$SERVER/tmp -U$DC_USERNAME%$DC_PASSWORD') > elif t == "rpc.srvsvc": >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index bf3dd98cbef..3f55649f217 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -342,6 +342,7 @@ smb2_s3only = [ > "smb2.kernel-oplocks", > "smb2.durable-v2-delay", > "smb2.aio_delay", >+ "smb2.fileid", > ] > smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only] > >diff --git a/source4/torture/smb2/create.c b/source4/torture/smb2/create.c >index 9b32062ab07..beddefc4c8d 100644 >--- a/source4/torture/smb2/create.c >+++ b/source4/torture/smb2/create.c >@@ -1905,6 +1905,204 @@ done: > return ret; > } > >+static bool test_fileid(struct torture_context *tctx, >+ struct smb2_tree *tree) >+{ >+ TALLOC_CTX *mem_ctx = talloc_new(tctx); >+ const char *fname = DNAME "\\foo"; >+ const char *sname = DNAME "\\foo:bar"; >+ struct smb2_handle testdirh; >+ struct smb2_handle h1; >+ struct smb2_create create; >+ union smb_fileinfo finfo; >+ union smb_setfileinfo sinfo; >+ struct smb2_find f; >+ unsigned int count; >+ union smb_search_data *d; >+ uint64_t fileid; >+ uint64_t stream_fileid; >+ NTSTATUS status; >+ bool ret = true; >+ >+ smb2_deltree(tree, DNAME); >+ >+ status = torture_smb2_testdir(tree, DNAME, &testdirh); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir failed\n"); >+ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN_IF, >+ .in.fname = fname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ >+ fileid = BVAL(&create.out.on_disk_id, 0); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ ret, done, "bad fileid\n"); >+ >+ f = (struct smb2_find) { >+ .in.file.handle = testdirh, >+ .in.pattern = "foo", >+ .in.max_response_size = 0x1000, >+ .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >+ }; >+ >+ status = smb2_find_level(tree, tree, &f, &count, &d); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_find_level failed\n"); >+ >+ torture_assert_u64_equal_goto(tctx, >+ d->id_both_directory_info.file_id, >+ fileid, >+ ret, done, "bad fileid\n"); >+ >+ smb2_util_close(tree, h1); >+ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF, >+ .in.fname = sname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ >+ stream_fileid = BVAL(&create.out.on_disk_id, 0); >+ torture_assert_u64_equal_goto(tctx, stream_fileid, fileid, >+ ret, done, "bad fileid\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ ret, done, "bad fileid\n"); >+ >+ f = (struct smb2_find) { >+ .in.file.handle = testdirh, >+ .in.pattern = "foo", >+ .in.max_response_size = 0x1000, >+ .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >+ .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART, >+ }; >+ >+ status = smb2_find_level(tree, tree, &f, &count, &d); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_find_level failed\n"); >+ >+ torture_assert_u64_equal_goto(tctx, >+ d->id_both_directory_info.file_id, >+ fileid, >+ ret, done, "bad fileid\n"); >+ >+ status = smb2_util_write(tree, h1, "foo", 0, strlen("foo")); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_util_write failed\n"); >+ >+ sinfo = (union smb_setfileinfo) { >+ .basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION, >+ .basic_info.in.file.handle = h1, >+ }; >+ unix_to_nt_time(&sinfo.basic_info.in.write_time, time(NULL)); >+ >+ status = smb2_setinfo_file(tree, &sinfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_setinfo_file failed\n"); >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_getinfo_file failed\n"); >+ >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ ret, done, "bad fileid\n"); >+ >+ smb2_util_close(tree, h1); >+ >+ create = (struct smb2_create) { >+ .in.desired_access = SEC_FILE_ALL, >+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, >+ .in.file_attributes = FILE_ATTRIBUTE_NORMAL, >+ .in.create_disposition = NTCREATEX_DISP_OPEN, >+ .in.fname = fname, >+ .in.query_on_disk_id = true, >+ }; >+ >+ status = smb2_create(tree, tctx, &create); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "test file could not be created\n"); >+ h1 = create.out.file.handle; >+ >+ finfo = (union smb_fileinfo) { >+ .generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION, >+ .generic.in.file.handle = h1, >+ }; >+ >+ status = smb2_getinfo_file(tree, tctx, &finfo); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "torture_smb2_testdir\n"); >+ >+ torture_assert_u64_equal_goto(tctx, finfo.all_info2.out.file_id, fileid, >+ ret, done, "bad fileid\n"); >+ >+ f = (struct smb2_find) { >+ .in.file.handle = testdirh, >+ .in.pattern = "foo", >+ .in.max_response_size = 0x1000, >+ .in.level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO, >+ .in.continue_flags = SMB2_CONTINUE_FLAG_RESTART, >+ }; >+ >+ status = smb2_find_level(tree, tree, &f, &count, &d); >+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, >+ "smb2_find_level failed\n"); >+ >+ torture_assert_u64_equal_goto(tctx, >+ d->id_both_directory_info.file_id, >+ fileid, >+ ret, done, "bad fileid\n"); >+ >+ smb2_util_close(tree, h1); >+ >+done: >+ smb2_util_close(tree, testdirh); >+ smb2_deltree(tree, DNAME); >+ talloc_free(mem_ctx); >+ return ret; >+} >+ > /* > basic testing of SMB2 read > */ >@@ -1942,3 +2140,17 @@ struct torture_suite *torture_smb2_twrp_init(TALLOC_CTX *ctx) > > return suite; > } >+ >+/* >+ basic testing of SMB2 File-IDs >+*/ >+struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx) >+{ >+ struct torture_suite *suite = torture_suite_create(ctx, "fileid"); >+ >+ torture_suite_add_1smb2_test(suite, "fileid", test_fileid); >+ >+ suite->description = talloc_strdup(suite, "SMB2-CREATE tests"); >+ >+ return suite; >+} >diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c >index e57dba3c1d9..7cca19e65d3 100644 >--- a/source4/torture/smb2/smb2.c >+++ b/source4/torture/smb2/smb2.c >@@ -155,6 +155,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx) > torture_suite_add_suite(suite, torture_smb2_aio_delay_init(suite)); > torture_suite_add_suite(suite, torture_smb2_create_init(suite)); > torture_suite_add_suite(suite, torture_smb2_twrp_init(suite)); >+ torture_suite_add_suite(suite, torture_smb2_fileid_init(suite)); > torture_suite_add_suite(suite, torture_smb2_acls_init(suite)); > torture_suite_add_suite(suite, torture_smb2_notify_init(suite)); > torture_suite_add_suite(suite, torture_smb2_notify_inotify_init(suite)); >-- >2.17.1 > > >From cca34da443ed6ee530fcf8c0def63d4b00527ffd Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Tue, 3 Sep 2019 17:50:54 +0200 >Subject: [PATCH 180/376] lib: add round_timespec_to_nttime() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 5403bb22e6cb39baf6dc1b91558744d41e9f6f64) >--- > lib/util/time.c | 9 +++++++++ > lib/util/time.h | 1 + > 2 files changed, 10 insertions(+) > >diff --git a/lib/util/time.c b/lib/util/time.c >index bd067f84e8e..3a6043025f4 100644 >--- a/lib/util/time.c >+++ b/lib/util/time.c >@@ -956,6 +956,15 @@ void round_timespec_to_usec(struct timespec *ts) > } > } > >+/**************************************************************************** >+ Round a timespec to NTTIME resolution. >+****************************************************************************/ >+ >+void round_timespec_to_nttime(struct timespec *ts) >+{ >+ ts->tv_nsec = (ts->tv_nsec / 100) * 100; >+} >+ > /**************************************************************************** > Put a 8 byte filetime from a struct timespec. Uses GMT. > ****************************************************************************/ >diff --git a/lib/util/time.h b/lib/util/time.h >index 1988b330576..7a8f8af35d9 100644 >--- a/lib/util/time.h >+++ b/lib/util/time.h >@@ -328,6 +328,7 @@ struct timespec timespec_min(const struct timespec *ts1, > int timespec_compare(const struct timespec *ts1, const struct timespec *ts2); > void round_timespec_to_sec(struct timespec *ts); > void round_timespec_to_usec(struct timespec *ts); >+void round_timespec_to_nttime(struct timespec *ts); > NTTIME unix_timespec_to_nt_time(struct timespec ts); > > #endif /* _SAMBA_TIME_H_ */ >-- >2.17.1 > > >From 6dfeecf345c0a009fff6b233241156eff3160467 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 9 Sep 2019 11:12:08 +0200 >Subject: [PATCH 181/376] s3:lib: round itime to NTTIME resolution in > make_file_id_from_itime() > >The rounding is needed because when a file is created via eg an SMB2 CREATE >request, we need to calculate the correct File-ID for the QFID Create-Context or >for a subsequent GETINFO SMB request on the same file-handle. > >Any later metadata request that received the File-ID will do so by going through >dos_mode() -> ... -> parse_dos_attribute_blob(), where the File-ID will be >calculated from the on-disk itime which has NTTIME resolution. > >As long as that is the only available itime backend, I'm rounding itime inside >make_file_id_from_itime(), not in the callers. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 84abeaa60ffced276da2b28b8add6efaa6da5ca6) >--- > source3/lib/file_id.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c >index 7d4fb006afe..21f22ffbf3b 100644 >--- a/source3/lib/file_id.c >+++ b/source3/lib/file_id.c >@@ -102,6 +102,8 @@ uint64_t make_file_id_from_itime(SMB_STRUCT_STAT *st) > return ino; > } > >+ round_timespec_to_nttime(&itime); >+ > file_id_low = itime.tv_nsec; > if (file_id_low == 0) { > /* >-- >2.17.1 > > >From d47f8ca1a769571dae73081cda6a01812c1a256c Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 30 Aug 2019 14:48:40 +0200 >Subject: [PATCH 182/376] s3:smbd: ensure to update the File-ID in struct > smb_filename > >Initialize the File-ID in fsp->fsp_name->st, any subsequent metadata fetch on >this file-handle needs this, eg QFID SMB2 Create-Context or GETINFO SMB >requests. > >It would be nice if SMB_VFS_SET_DOS_ATTRIBUTE() would do this, unfortunately it >gets a const struct smb_filename. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 3483b75fed8985bd2968bbf8c85985107115fba8) >--- > source3/smbd/open.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 2ee4a2c4fca..a5650ac9c2d 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -3710,6 +3710,15 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, > > if (info == FILE_WAS_CREATED) { > smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME; >+ >+ if (lp_store_dos_attributes(SNUM(conn)) && >+ smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID) >+ { >+ uint64_t file_id; >+ >+ file_id = make_file_id_from_itime(&smb_fname->st); >+ update_stat_ex_file_id(&smb_fname->st, file_id); >+ } > } > > if (info != FILE_WAS_OPENED) { >@@ -3862,6 +3871,14 @@ static NTSTATUS mkdir_internal(connection_struct *conn, > smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME; > > if (lp_store_dos_attributes(SNUM(conn))) { >+ if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID) >+ { >+ uint64_t file_id; >+ >+ file_id = make_file_id_from_itime(&smb_dname->st); >+ update_stat_ex_file_id(&smb_dname->st, file_id); >+ } >+ > if (!posix_open) { > file_set_dosmode(conn, smb_dname, > file_attributes | FILE_ATTRIBUTE_DIRECTORY, >-- >2.17.1 > > >From 4930920648ad6879a72c77d79508025478dcbaa2 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 30 Aug 2019 14:48:57 +0200 >Subject: [PATCH 183/376] vfs_catia: stat info may have been updated, make sure > to return changes > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 4e49999c97f53acc7006f1dc6b6812bb0e156db5) >--- > source3/modules/vfs_catia.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c >index 762491ede31..1869d21dbcf 100644 >--- a/source3/modules/vfs_catia.c >+++ b/source3/modules/vfs_catia.c >@@ -2377,6 +2377,10 @@ static NTSTATUS catia_get_dos_attributes(struct vfs_handle_struct *handle, > status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, > mapped_smb_fname, > dosmode); >+ if (NT_STATUS_IS_OK(status)) { >+ smb_fname->st = mapped_smb_fname->st; >+ } >+ > TALLOC_FREE(mapped_name); > TALLOC_FREE(mapped_smb_fname); > >-- >2.17.1 > > >From cb09104951cdefba991464e486c536b06356fd25 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Fri, 30 Aug 2019 14:49:47 +0200 >Subject: [PATCH 184/376] s3:lib: add update_stat_ex_from_saved_stat() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit ac18730f10ce96a607a3a07e1360b522ebf72f38) >--- > source3/include/proto.h | 2 ++ > source3/lib/system.c | 20 ++++++++++++++++++++ > 2 files changed, 22 insertions(+) > >diff --git a/source3/include/proto.h b/source3/include/proto.h >index 8b387f7c563..ad6f3bbf9c3 100644 >--- a/source3/include/proto.h >+++ b/source3/include/proto.h >@@ -223,6 +223,8 @@ void update_stat_ex_mtime(struct stat_ex *dst, struct timespec write_ts); > void update_stat_ex_itime(struct stat_ex *dst, struct timespec itime); > void update_stat_ex_create_time(struct stat_ex *dst, struct timespec create_time); > void update_stat_ex_file_id(struct stat_ex *dst, uint64_t file_id); >+void update_stat_ex_from_saved_stat(struct stat_ex *dst, >+ const struct stat_ex *src); > int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf, > bool fake_dir_create_times); > int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf, >diff --git a/source3/lib/system.c b/source3/lib/system.c >index a67388e436a..0620439c944 100644 >--- a/source3/lib/system.c >+++ b/source3/lib/system.c >@@ -355,6 +355,26 @@ void update_stat_ex_file_id(struct stat_ex *dst, uint64_t file_id) > dst->st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_FILE_ID; > } > >+void update_stat_ex_from_saved_stat(struct stat_ex *dst, >+ const struct stat_ex *src) >+{ >+ if (!VALID_STAT(*src)) { >+ return; >+ } >+ >+ if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_BTIME)) { >+ update_stat_ex_create_time(dst, src->st_ex_btime); >+ } >+ >+ if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_ITIME)) { >+ update_stat_ex_itime(dst, src->st_ex_itime); >+ } >+ >+ if (!(src->st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)) { >+ update_stat_ex_file_id(dst, src->st_ex_file_id); >+ } >+} >+ > void init_stat_ex_from_stat (struct stat_ex *dst, > const struct stat *src, > bool fake_dir_create_times) >-- >2.17.1 > > >From b14dd975c754be30d247591190bec5db3f305245 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 9 Sep 2019 07:57:34 +0200 >Subject: [PATCH 185/376] s3: replace fsp_stat() with vfs_stat_fsp() > >Both functions do the same, they differ just in the type of the returned result. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit ab03394969f8a4c748aea7d0d8ed37f9ced6cc30) >--- > source3/modules/vfs_dirsort.c | 13 ++++++++----- > source3/smbd/fileio.c | 17 ----------------- > source3/smbd/proto.h | 1 - > source3/smbd/reply.c | 23 +++++++++++++++-------- > 4 files changed, 23 insertions(+), 31 deletions(-) > >diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c >index c23f6f0152d..c6b5ea41c93 100644 >--- a/source3/modules/vfs_dirsort.c >+++ b/source3/modules/vfs_dirsort.c >@@ -44,19 +44,22 @@ static bool get_sorted_dir_mtime(vfs_handle_struct *handle, > { > int ret; > struct timespec mtime; >+ NTSTATUS status; > > if (data->fsp) { >- ret = fsp_stat(data->fsp); >+ status = vfs_stat_fsp(data->fsp); >+ if (!NT_STATUS_IS_OK(status)) { >+ return false; >+ } > mtime = data->fsp->fsp_name->st.st_ex_mtime; > } else { > ret = SMB_VFS_STAT(handle->conn, data->smb_fname); >+ if (ret == -1) { >+ return false; >+ } > mtime = data->smb_fname->st.st_ex_mtime; > } > >- if (ret == -1) { >- return false; >- } >- > *ret_mtime = mtime; > > return true; >diff --git a/source3/smbd/fileio.c b/source3/smbd/fileio.c >index a00b368f92b..067ce5a9ad4 100644 >--- a/source3/smbd/fileio.c >+++ b/source3/smbd/fileio.c >@@ -1068,20 +1068,3 @@ NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_throug > } > return NT_STATUS_OK; > } >- >-/************************************************************ >- Perform a stat whether a valid fd or not. >-************************************************************/ >- >-int fsp_stat(files_struct *fsp) >-{ >- if (fsp->fh->fd == -1) { >- if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { >- return SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name); >- } else { >- return SMB_VFS_STAT(fsp->conn, fsp->fsp_name); >- } >- } else { >- return SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); >- } >-} >diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h >index cd1ec9a1f9e..10ffaf6e480 100644 >--- a/source3/smbd/proto.h >+++ b/source3/smbd/proto.h >@@ -342,7 +342,6 @@ void delete_write_cache(files_struct *fsp); > void set_filelen_write_cache(files_struct *fsp, off_t file_size); > ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason); > NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through); >-int fsp_stat(files_struct *fsp); > > /* The following definitions come from smbd/filename.c */ > >diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c >index dec67a10cae..35d1ae772d5 100644 >--- a/source3/smbd/reply.c >+++ b/source3/smbd/reply.c >@@ -3662,6 +3662,7 @@ void reply_readbraw(struct smb_request *req) > files_struct *fsp; > struct lock_struct lock; > off_t size = 0; >+ NTSTATUS status; > > START_PROFILE(SMBreadbraw); > >@@ -3759,7 +3760,8 @@ void reply_readbraw(struct smb_request *req) > return; > } > >- if (fsp_stat(fsp) == 0) { >+ status = vfs_stat_fsp(fsp); >+ if (NT_STATUS_IS_OK(status)) { > size = fsp->fsp_name->st.st_ex_size; > } > >@@ -4090,6 +4092,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, > ssize_t nread = -1; > struct lock_struct lock; > int saved_errno = 0; >+ NTSTATUS status; > > init_strict_lock_struct(fsp, (uint64_t)req->smbpid, > (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK, >@@ -4114,8 +4117,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, > uint8_t headerbuf[smb_size + 12 * 2 + 1 /* padding byte */]; > DATA_BLOB header; > >- if(fsp_stat(fsp) == -1) { >- reply_nterror(req, map_nt_error_from_unix(errno)); >+ status = vfs_stat_fsp(fsp); >+ if (!NT_STATUS_IS_OK(status)) { >+ reply_nterror(req, status); > goto out; > } > >@@ -5323,6 +5327,7 @@ void reply_lseek(struct smb_request *req) > off_t res= -1; > int mode,umode; > files_struct *fsp; >+ NTSTATUS status; > > START_PROFILE(SMBlseek); > >@@ -5367,9 +5372,9 @@ void reply_lseek(struct smb_request *req) > if(errno == EINVAL) { > off_t current_pos = startpos; > >- if(fsp_stat(fsp) == -1) { >- reply_nterror(req, >- map_nt_error_from_unix(errno)); >+ status = vfs_stat_fsp(fsp); >+ if (!NT_STATUS_IS_OK(status)) { >+ reply_nterror(req, status); > END_PROFILE(SMBlseek); > return; > } >@@ -8739,6 +8744,7 @@ void reply_getattrE(struct smb_request *req) > int mode; > files_struct *fsp; > struct timespec create_ts; >+ NTSTATUS status; > > START_PROFILE(SMBgetattrE); > >@@ -8757,8 +8763,9 @@ void reply_getattrE(struct smb_request *req) > } > > /* Do an fstat on this file */ >- if(fsp_stat(fsp)) { >- reply_nterror(req, map_nt_error_from_unix(errno)); >+ status = vfs_stat_fsp(fsp); >+ if (!NT_STATUS_IS_OK(status)) { >+ reply_nterror(req, status); > END_PROFILE(SMBgetattrE); > return; > } >-- >2.17.1 > > >From b4aaa612d33caf51b44830d75997d4ad93b7740d Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 9 Sep 2019 08:03:53 +0200 >Subject: [PATCH 186/376] s3:vfs: streamline vfs_stat_fsp() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit e00e78cfeda99bd5374eff8fb4ba84873e4e46b7) >--- > source3/smbd/vfs.c | 10 ++++------ > 1 file changed, 4 insertions(+), 6 deletions(-) > >diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c >index 51a4aeb0f22..67f7d6356a2 100644 >--- a/source3/smbd/vfs.c >+++ b/source3/smbd/vfs.c >@@ -1413,13 +1413,11 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp) > } else { > ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name); > } >- if (ret == -1) { >- return map_nt_error_from_unix(errno); >- } > } else { >- if(SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) != 0) { >- return map_nt_error_from_unix(errno); >- } >+ ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); >+ } >+ if (ret == -1) { >+ return map_nt_error_from_unix(errno); > } > return NT_STATUS_OK; > } >-- >2.17.1 > > >From d887047aa0c2489d1d6251ffcb9ce083e86866e1 Mon Sep 17 00:00:00 2001 >From: Ralph Boehme <slow@samba.org> >Date: Mon, 9 Sep 2019 08:08:06 +0200 >Subject: [PATCH 187/376] vfs: restore stat fields in vfs_stat_fsp() >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This ensures we preserve btime, itime and File-ID. > >As the Durable Handles code calls vfs_stat_fsp() in the DH disconnect function, >previously the btime was lost and NOT stored in the cookie. With this change the >cookie will store the correct btime (and iflags), which requires us to call >dos_mode() in the reconnect function to ensure we pass >vfs_default_durable_reconnect_check_stat(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14121 > >Signed-off-by: Ralph Boehme <slow@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Ralph Böhme <slow@samba.org> >Autobuild-Date(master): Tue Sep 10 20:22:21 UTC 2019 on sn-devel-184 > >(cherry picked from commit 95655fe683d499d93f3844ed72ad332ef64adb96) > >Autobuild-User(v4-11-test): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(v4-11-test): Tue Sep 10 22:29:08 UTC 2019 on sn-devel-184 >--- > selftest/knownfail.d/samba3.smb2.create | 1 - > source3/smbd/durable.c | 2 ++ > source3/smbd/vfs.c | 2 ++ > 3 files changed, 4 insertions(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/samba3.smb2.create > >diff --git a/selftest/knownfail.d/samba3.smb2.create b/selftest/knownfail.d/samba3.smb2.create >deleted file mode 100644 >index 89455dacdf0..00000000000 >--- a/selftest/knownfail.d/samba3.smb2.create >+++ /dev/null >@@ -1 +0,0 @@ >-^samba3.smb2.fileid.fileid\(nt4_dc\) >diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c >index 4aa5a2d619e..89c4c1e8d14 100644 >--- a/source3/smbd/durable.c >+++ b/source3/smbd/durable.c >@@ -842,6 +842,8 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, > return NT_STATUS_OBJECT_NAME_NOT_FOUND; > } > >+ (void)dos_mode(fsp->conn, fsp->fsp_name); >+ > ok = vfs_default_durable_reconnect_check_stat(&cookie.stat_info, > &fsp->fsp_name->st, > fsp_str_dbg(fsp)); >diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c >index 67f7d6356a2..c8437a0c6c9 100644 >--- a/source3/smbd/vfs.c >+++ b/source3/smbd/vfs.c >@@ -1406,6 +1406,7 @@ int vfs_stat_smb_basename(struct connection_struct *conn, > NTSTATUS vfs_stat_fsp(files_struct *fsp) > { > int ret; >+ struct stat_ex saved_stat = fsp->fsp_name->st; > > if(fsp->fh->fd == -1) { > if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { >@@ -1419,6 +1420,7 @@ NTSTATUS vfs_stat_fsp(files_struct *fsp) > if (ret == -1) { > return map_nt_error_from_unix(errno); > } >+ update_stat_ex_from_saved_stat(&fsp->fsp_name->st, &saved_stat); > return NT_STATUS_OK; > } > >-- >2.17.1 > > >From 76eab3e6bc9631437719bf9a7fbabb8e77ceb20a Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 10 Sep 2019 13:02:12 +0200 >Subject: [PATCH 188/376] WHATSNEW: Remove paragraph about rejoining DCs. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 5 ----- > 1 file changed, 5 deletions(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index 904db5fefc3..9069ca664ab 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -33,11 +33,6 @@ When either upgrading or downgrading, users should also avoid making any > database modifications between installing the new Samba packages and starting > the samba executable. > >-Note that when moving between major Samba releases in general, we recommend >-that the AD DC is rejoined to the domain. Using this approach avoids the need >-to explicitly downgrade the database manually. For more details, see: >-https://wiki.samba.org/index.php/Upgrading_a_Samba_AD_DC >- > SMB1 is disabled by default > --------------------------- > >-- >2.17.1 > > >From 70906342a77e431e0ea5b482b9f35aa26a5d64bc Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 10 Sep 2019 09:19:32 +0200 >Subject: [PATCH 189/376] WHATSNEW: Add release notes for Samba 4.11.0rc4. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 41 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 40 insertions(+), 1 deletion(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index 9069ca664ab..74d1de4c021 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -1,7 +1,7 @@ > Release Announcements > ===================== > >-This is the third release candidate of Samba 4.11. This is *not* >+This is the fourth release candidate of Samba 4.11. This is *not* > intended for production environments and is designed for testing > purposes only. Please report any defects via the Samba bug reporting > system at https://bugzilla.samba.org/. >@@ -368,6 +368,45 @@ smb.conf changes > encrypt passwords Deprecated > > >+CHANGES SINCE 4.11.0rc3 >+======================= >+ >+o Douglas Bagnall <douglas.bagnall@catalyst.net.nz> >+ * BUG 14049: ldb: Don't try to save a value that isn't there. >+ * ldb_dn: Free dn components on explode failure. >+ * ldb: Do not allow adding a DN as a base to itself. >+ >+o Andrew Bartlett <abartlet@samba.org> >+ * ldb: Release ldb 2.0.7. >+ * BUG 13695: ldb: Correct Pigeonhole principle validation in >+ ldb_filter_attrs(). >+ * BUG 14049: Fix ldb dn crash. >+ * BUG 14117: Deprecate "lanman auth = yes" and "encrypt passwords = no". >+ >+o Ralph Boehme <slow@samba.org> >+ * BUG 14038: Fix compiling ctdb on older systems lacking POSIX robust >+ mutexes. >+ * BUG 14121: smbd returns bad File-ID on filehandle used to create a file or >+ directory. >+ >+o Poornima G <pgurusid@redhat.com> >+ * BUG 14098: vfs_glusterfs: Use pthreadpool for scheduling aio operations. >+ >+o Stefan Metzmacher <metze@samba.org> >+ * BUG 14055: Add the target server name of SMB 3.1.1 connections as a hint to >+ load balancers or servers with "multi-tenancy" support. >+ * BUG 14113: Fix byte range locking bugs/regressions. >+ >+o Swen Schillig <swen@linux.ibm.com> >+ * ldb: Fix mem-leak if talloc_realloc fails. >+ >+o Evgeny Sinelnikov <sin@altlinux.org> >+ * BUG 14007: Fix join with don't exists machine account. >+ >+o Martin Schwenke <martin@meltin.net> >+ * BUG 14085: ctdb-recoverd: Only check for LMASTER nodes in the VNN map. >+ >+ > CHANGES SINCE 4.11.0rc2 > ======================= > >-- >2.17.1 > > >From b788d502cd187d1d71310ab9384e0b2445062491 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 10 Sep 2019 13:00:53 +0200 >Subject: [PATCH 190/376] VERSION: Disable GIT_SNAPSHOT for the 4.11.0rc4 > release. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/VERSION b/VERSION >index ae98c26560f..792dd684a3c 100644 >--- a/VERSION >+++ b/VERSION >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=4 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=yes >+SAMBA_VERSION_IS_GIT_SNAPSHOT=no > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From 4f2bbe2ed1d8d90c4c3311a8b77e1f695e66bea4 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 10 Sep 2019 13:19:03 +0200 >Subject: [PATCH 191/376] VERSION: Bump version up to 4.11.0rc5... > >and re-enable GIT_SNAPSHOT. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index 792dd684a3c..e3cbecc1d16 100644 >--- a/VERSION >+++ b/VERSION >@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= > # e.g. SAMBA_VERSION_RC_RELEASE=1 # > # -> "3.0.0rc1" # > ######################################################## >-SAMBA_VERSION_RC_RELEASE=4 >+SAMBA_VERSION_RC_RELEASE=5 > > ######################################################## > # To mark SVN snapshots this should be set to 'yes' # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=4 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=no >+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From e0886709582a12b37cec4299172570169f986056 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 17 Sep 2019 10:00:54 +0200 >Subject: [PATCH 192/376] WHATSNEW: Add release notes for Samba 4.11.0. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > WHATSNEW.txt | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > >diff --git a/WHATSNEW.txt b/WHATSNEW.txt >index 74d1de4c021..d573bb65819 100644 >--- a/WHATSNEW.txt >+++ b/WHATSNEW.txt >@@ -1,12 +1,11 @@ >-Release Announcements >-===================== >+ ============================== >+ Release Notes for Samba 4.11.0 >+ September 17, 2019 >+ ============================== > >-This is the fourth release candidate of Samba 4.11. This is *not* >-intended for production environments and is designed for testing >-purposes only. Please report any defects via the Samba bug reporting >-system at https://bugzilla.samba.org/. > >-Samba 4.11 will be the next version of the Samba suite. >+This is the first stable release of the Samba 4.11 release series. >+Please read the release notes carefully before upgrading. > > > UPGRADING >@@ -368,6 +367,10 @@ smb.conf changes > encrypt passwords Deprecated > > >+CHANGES SINCE 4.11.0rc4 >+======================= >+ >+ > CHANGES SINCE 4.11.0rc3 > ======================= > >-- >2.17.1 > > >From d60cf580825819f11de9e50ec4c4ce591d695ad9 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 17 Sep 2019 10:02:02 +0200 >Subject: [PATCH 193/376] VERSION: Bump version up to 4.11.0... > >and disable GIT_SNAPSHOT for the 4.11.0 release. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index e3cbecc1d16..29a4ca4e959 100644 >--- a/VERSION >+++ b/VERSION >@@ -87,7 +87,7 @@ SAMBA_VERSION_PRE_RELEASE= > # e.g. SAMBA_VERSION_RC_RELEASE=1 # > # -> "3.0.0rc1" # > ######################################################## >-SAMBA_VERSION_RC_RELEASE=5 >+SAMBA_VERSION_RC_RELEASE= > > ######################################################## > # To mark SVN snapshots this should be set to 'yes' # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE=5 > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=yes >+SAMBA_VERSION_IS_GIT_SNAPSHOT=no > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From 872e03c2dc859759fe17228068701865023b16b5 Mon Sep 17 00:00:00 2001 >From: Karolin Seeger <kseeger@samba.org> >Date: Tue, 17 Sep 2019 10:03:08 +0200 >Subject: [PATCH 194/376] VERSION: Bump version up to 4.11.1... > >and re-enable GIT_SNAPSHOT. > >Signed-off-by: Karolin Seeger <kseeger@samba.org> >--- > VERSION | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/VERSION b/VERSION >index 29a4ca4e959..137edf08bba 100644 >--- a/VERSION >+++ b/VERSION >@@ -25,7 +25,7 @@ > ######################################################## > SAMBA_VERSION_MAJOR=4 > SAMBA_VERSION_MINOR=11 >-SAMBA_VERSION_RELEASE=0 >+SAMBA_VERSION_RELEASE=1 > > ######################################################## > # If a official release has a serious bug # >@@ -99,7 +99,7 @@ SAMBA_VERSION_RC_RELEASE= > # e.g. SAMBA_VERSION_IS_SVN_SNAPSHOT=yes # > # -> "3.0.0-SVN-build-199" # > ######################################################## >-SAMBA_VERSION_IS_GIT_SNAPSHOT=no >+SAMBA_VERSION_IS_GIT_SNAPSHOT=yes > > ######################################################## > # This is for specifying a release nickname # >-- >2.17.1 > > >From a0342e92f3a25fbf15ab0f3ad3f05e597726be81 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 26 Aug 2019 09:54:06 -0700 >Subject: [PATCH 195/376] s3: libsmbclient: Ensure SMBC_readdir_ctx() also > updates the readdirplus pointers. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >If we are returning file entries, we >have a duplicate list in dirplus. > >Update dirplus_next also so readdir and >readdirplus are kept in sync. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14094 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >(cherry picked from commit 4bca8e097f5a909c628daa4dbfa932ddc1725ebc) >--- > source3/libsmb/libsmb_dir.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c >index 886aa626509..a3ec9a8ff71 100644 >--- a/source3/libsmb/libsmb_dir.c >+++ b/source3/libsmb/libsmb_dir.c >@@ -1174,6 +1174,17 @@ SMBC_readdir_ctx(SMBCCTX *context, > > dir->dir_next = dir->dir_next->next; > >+ /* >+ * If we are returning file entries, we >+ * have a duplicate list in dirplus. >+ * >+ * Update dirplus_next also so readdir and >+ * readdirplus are kept in sync. >+ */ >+ if (dir->dirplus_list != NULL) { >+ dir->dirplus_next = dir->dirplus_next->next; >+ } >+ > TALLOC_FREE(frame); > return dirp; > } >-- >2.17.1 > > >From 0fbd2c08b548bd2588de960a5475ed5fc2de9bf7 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 26 Aug 2019 10:02:47 -0700 >Subject: [PATCH 196/376] s3: libsmbclient: Ensure SMBC_readdirplus_ctx() also > updates the readdir pointers. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >If we are returning file entries, we >have a duplicate list in dir_list. > >Update dir_next also so readdir and >readdirplus are kept in sync. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14094 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >(cherry picked from commit 3d82b7d11cd7b78adc6b3642e64e3a8f251de869) >--- > source3/libsmb/libsmb_dir.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c >index a3ec9a8ff71..2f2117e8131 100644 >--- a/source3/libsmb/libsmb_dir.c >+++ b/source3/libsmb/libsmb_dir.c >@@ -1231,6 +1231,17 @@ SMBC_readdirplus_ctx(SMBCCTX *context, > } > dir->dirplus_next = dir->dirplus_next->next; > >+ /* >+ * If we are returning file entries, we >+ * have a duplicate list in dir_list >+ * >+ * Update dir_next also so readdir and >+ * readdirplus are kept in sync. >+ */ >+ if (dir->dir_list) { >+ dir->dir_next = dir->dir_next->next; >+ } >+ > TALLOC_FREE(frame); > return smb_finfo; > } >-- >2.17.1 > > >From a70eee31213189d9cf0e4b40d14e2c301ef4f2c8 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 26 Aug 2019 10:07:32 -0700 >Subject: [PATCH 197/376] s3: libsmbclient: Ensure SMBC_getdents_ctx() also > updates the readdirplus pointers. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >If we are returning file entries, we >have a duplicate list in dirplus. > >Update dirplus_next also so readdir and >readdirplus are kept in sync. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14094 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >(cherry picked from commit 754cec7756b2ddb1cfcc3984265f01cb366beb76) >--- > source3/libsmb/libsmb_dir.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > >diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c >index 2f2117e8131..4447806c108 100644 >--- a/source3/libsmb/libsmb_dir.c >+++ b/source3/libsmb/libsmb_dir.c >@@ -1358,6 +1358,17 @@ SMBC_getdents_ctx(SMBCCTX *context, > } > > dir->dir_next = dirlist = dirlist -> next; >+ >+ /* >+ * If we are returning file entries, we >+ * have a duplicate list in dirplus. >+ * >+ * Update dirplus_next also so readdir and >+ * readdirplus are kept in sync. >+ */ >+ if (dir->dirplus_list != NULL) { >+ dir->dirplus_next = dir->dirplus_next->next; >+ } > } > > TALLOC_FREE(frame); >-- >2.17.1 > > >From 411eb45f2c9b9019d8a54c3c7092a3c0fc515e15 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 26 Aug 2019 10:18:28 -0700 >Subject: [PATCH 198/376] s3: libsmbclient: Fix smbc_lseekdir() to work with > smbc_readdirplus(). >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >If returning files the dir_list and the dirplus_list have exactly the same >entries, we just need to keep the next pointers in sync on seek. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14094 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >(cherry picked from commit 0d9b1645499ce12a79a137d3482434aa5d2eb47c) >--- > source3/libsmb/libsmb_dir.c | 69 +++++++++++++++++++++++-------------- > 1 file changed, 43 insertions(+), 26 deletions(-) > >diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c >index 4447806c108..df606c4adfe 100644 >--- a/source3/libsmb/libsmb_dir.c >+++ b/source3/libsmb/libsmb_dir.c >@@ -1672,35 +1672,43 @@ SMBC_telldir_ctx(SMBCCTX *context, > > /* > * A routine to run down the list and see if the entry is OK >+ * Modifies the dir list and the dirplus list (if it exists) >+ * to point at the correct next entry on success. > */ > >-static struct smbc_dir_list * >-check_dir_ent(struct smbc_dir_list *list, >- struct smbc_dirent *dirent) >+static bool update_dir_ents(SMBCFILE *dir, struct smbc_dirent *dirent) > { >+ struct smbc_dir_list *tmp_dir = dir->dir_list; >+ struct smbc_dirplus_list *tmp_dirplus = dir->dirplus_list; > >- /* Run down the list looking for what we want */ >- >- if (dirent) { >- >- struct smbc_dir_list *tmp = list; >- >- while (tmp) { >- >- if (tmp->dirent == dirent) >- return tmp; >- >- tmp = tmp->next; >+ /* >+ * Run down the list looking for what we want. >+ * If we're enumerating files both dir_list >+ * and dirplus_list contain the same entry >+ * list, as they were seeded from the same >+ * cli_list callback. >+ * >+ * If we're enumerating servers then >+ * dirplus_list will be NULL, so don't >+ * update in that case. >+ */ > >+ while (tmp_dir != NULL) { >+ if (tmp_dir->dirent == dirent) { >+ dir->dir_next = tmp_dir; >+ if (tmp_dirplus != NULL) { >+ dir->dirplus_next = tmp_dirplus; >+ } >+ return true; >+ } >+ tmp_dir = tmp_dir->next; >+ if (tmp_dirplus != NULL) { >+ tmp_dirplus = tmp_dirplus->next; > } >- > } >- >- return NULL; /* Not found, or an error */ >- >+ return false; > } > >- > /* > * Routine to seek on a directory > */ >@@ -1712,8 +1720,8 @@ SMBC_lseekdir_ctx(SMBCCTX *context, > { > long int l_offset = offset; /* Handle problems of size */ > struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; >- struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; > TALLOC_CTX *frame = talloc_stackframe(); >+ bool ok; > > if (!context || !context->internal->initialized) { > >@@ -1736,6 +1744,10 @@ SMBC_lseekdir_ctx(SMBCCTX *context, > if (dirent == NULL) { /* Seek to the begining of the list */ > > dir->dir_next = dir->dir_list; >+ >+ /* Do the same for dirplus. */ >+ dir->dirplus_next = dir->dirplus_list; >+ > TALLOC_FREE(frame); > return 0; > >@@ -1743,21 +1755,26 @@ SMBC_lseekdir_ctx(SMBCCTX *context, > > if (offset == -1) { /* Seek to the end of the list */ > dir->dir_next = NULL; >+ >+ /* Do the same for dirplus. */ >+ dir->dirplus_next = NULL; >+ > TALLOC_FREE(frame); > return 0; > } > >- /* Now, run down the list and make sure that the entry is OK */ >- /* This may need to be changed if we change the format of the list */ >+ /* >+ * Run down the list and make sure that the entry is OK. >+ * Update the position of both dir and dirplus lists. >+ */ > >- if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) { >+ ok = update_dir_ents(dir, dirent); >+ if (!ok) { > errno = EINVAL; /* Bad entry */ > TALLOC_FREE(frame); > return -1; > } > >- dir->dir_next = list_ent; >- > TALLOC_FREE(frame); > return 0; > } >-- >2.17.1 > > >From d702f66290159d72c8f3c5d08ec9e9f23772611f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 26 Aug 2019 11:22:35 -0700 >Subject: [PATCH 199/376] s3/4: libsmbclient test. Test using > smbc_telldir/smbc_lseekdir with smbc_readdir/smbc_readdirplus/smbc_getdents. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Ensure that for file access you can mix any of these >three access methods for directory entries and the >returned names/structs stay in sync across telldir/seekdir >changes. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14094 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Tue Sep 3 17:31:29 UTC 2019 on sn-devel-184 > >(cherry picked from commit 3355601fe8541994cc41f5ed800aab9b6a2294f4) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Sep 18 13:51:56 UTC 2019 on sn-devel-184 >--- > source3/selftest/tests.py | 3 +- > source4/torture/libsmbclient/libsmbclient.c | 340 ++++++++++++++++++++ > 2 files changed, 342 insertions(+), 1 deletion(-) > >diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py >index 20f2eea7661..5b5a1978988 100755 >--- a/source3/selftest/tests.py >+++ b/source3/selftest/tests.py >@@ -495,7 +495,8 @@ nbt = ["nbt.dgram"] > libsmbclient = ["libsmbclient.version", "libsmbclient.initialize", > "libsmbclient.configuration", "libsmbclient.setConfiguration", > "libsmbclient.options", "libsmbclient.opendir", >- "libsmbclient.list_shares", "libsmbclient.readdirplus"] >+ "libsmbclient.list_shares", "libsmbclient.readdirplus", >+ "libsmbclient.readdirplus_seek"] > > vfs = [ > "vfs.fruit", >diff --git a/source4/torture/libsmbclient/libsmbclient.c b/source4/torture/libsmbclient/libsmbclient.c >index f9154e8a19c..b74d87aabed 100644 >--- a/source4/torture/libsmbclient/libsmbclient.c >+++ b/source4/torture/libsmbclient/libsmbclient.c >@@ -18,6 +18,7 @@ > */ > > #include "includes.h" >+#include "system/dir.h" > #include "torture/smbtorture.h" > #include "auth/credentials/credentials.h" > #include "lib/cmdline/popt_common.h" >@@ -375,6 +376,343 @@ static bool torture_libsmbclient_readdirplus(struct torture_context *tctx) > return true; > } > >+static bool torture_libsmbclient_readdirplus_seek(struct torture_context *tctx) >+{ >+ SMBCCTX *ctx; >+ int ret = -1; >+ int dhandle = -1; >+ int fhandle = -1; >+ const char *dname = NULL; >+ const char *full_filename[100] = {0}; >+ const char *filename[100] = {0}; >+ const struct libsmb_file_info *direntries[102] = {0}; >+ unsigned int i = 0; >+ const char *smburl = torture_setting_string(tctx, "smburl", NULL); >+ bool success = false; >+ off_t telldir_50 = (off_t)-1; >+ off_t telldir_20 = (off_t)-1; >+ size_t getdentries_size = 0; >+ struct smbc_dirent *getdentries = NULL; >+ struct smbc_dirent *dirent_20 = NULL; >+ const struct libsmb_file_info *direntries_20 = NULL; >+ >+ if (smburl == NULL) { >+ torture_fail(tctx, >+ "option --option=torture:smburl=" >+ "smb://user:password@server/share missing\n"); >+ } >+ >+ DEBUG(0,("torture_libsmbclient_readdirplus_seek start\n")); >+ >+ torture_assert(tctx, torture_libsmbclient_init_context(tctx, &ctx), ""); >+ smbc_set_context(ctx); >+ >+ dname = talloc_asprintf(tctx, >+ "%s/rd_seek", >+ smburl); >+ if (dname == NULL) { >+ torture_fail_goto(tctx, >+ done, >+ "talloc fail\n"); >+ } >+ >+ /* Ensure the files don't exist. */ >+ for (i = 0; i < 100; i++) { >+ filename[i] = talloc_asprintf(tctx, >+ "test_readdirplus_%u.txt", >+ i); >+ if (filename[i] == NULL) { >+ torture_fail_goto(tctx, >+ done, >+ "talloc fail\n"); >+ } >+ full_filename[i] = talloc_asprintf(tctx, >+ "%s/%s", >+ dname, >+ filename[i]); >+ if (full_filename[i] == NULL) { >+ torture_fail_goto(tctx, >+ done, >+ "talloc fail\n"); >+ } >+ (void)smbc_unlink(full_filename[i]); >+ } >+ /* Ensure the directory doesn't exist. */ >+ (void)smbc_rmdir(dname); >+ >+ /* Create containing directory. */ >+ ret = smbc_mkdir(dname, 0777); >+ if (ret != 0) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "failed to create directory '%s': %s", >+ dname, >+ strerror(errno))); >+ } >+ >+ DEBUG(0,("torture_libsmbclient_readdirplus_seek create\n")); >+ >+ /* Create them. */ >+ for (i = 0; i < 100; i++) { >+ fhandle = smbc_creat(full_filename[i], 0666); >+ if (fhandle < 0) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "failed to create file '%s': %s", >+ full_filename[i], >+ strerror(errno))); >+ } >+ ret = smbc_close(fhandle); >+ torture_assert_int_equal_goto(tctx, >+ ret, >+ 0, >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "failed to close handle for '%s'", >+ full_filename[i])); >+ } >+ >+ DEBUG(0,("torture_libsmbclient_readdirplus_seek enum\n")); >+ >+ /* Now enumerate the directory. */ >+ dhandle = smbc_opendir(dname); >+ if (dhandle < 0) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "failed to obtain " >+ "directory handle for '%s' : %s", >+ dname, >+ strerror(errno))); >+ } >+ >+ /* Read all the files. 100 we created plus . and .. */ >+ for (i = 0; i < 102; i++) { >+ bool found = false; >+ unsigned int j; >+ >+ direntries[i] = smbc_readdirplus(dhandle); >+ if (direntries[i] == NULL) { >+ break; >+ } >+ >+ /* Store at offset 50. */ >+ if (i == 50) { >+ telldir_50 = smbc_telldir(dhandle); >+ if (telldir_50 == (off_t)-1) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "telldir failed file %s\n", >+ direntries[i]->name)); >+ } >+ } >+ >+ if (ISDOT(direntries[i]->name)) { >+ continue; >+ } >+ if (ISDOTDOT(direntries[i]->name)) { >+ continue; >+ } >+ >+ /* Ensure all our files exist. */ >+ for (j = 0; j < 100; j++) { >+ if (strcmp(direntries[i]->name, >+ filename[j]) == 0) { >+ found = true; >+ } >+ } >+ if (!found) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "failed to find file %s\n", >+ direntries[i]->name)); >+ } >+ } >+ >+ /* >+ * We're seeking on in-memory lists here, so >+ * whilst the handle is open we really should >+ * get the same files back in the same order. >+ */ >+ >+ ret = smbc_lseekdir(dhandle, telldir_50); >+ torture_assert_int_equal_goto(tctx, >+ ret, >+ 0, >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "failed to seek (50) directory handle for '%s'", >+ dname)); >+ >+ DEBUG(0,("torture_libsmbclient_readdirplus_seek seek\n")); >+ >+ for (i = 51; i < 102; i++) { >+ const struct libsmb_file_info *entry = >+ smbc_readdirplus(dhandle); >+ if (entry != direntries[i]) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "after seek - failed to find " >+ "file %s - got %s\n", >+ direntries[i]->name, >+ entry->name)); >+ } >+ } >+ >+ /* Seek back to the start. */ >+ ret = smbc_lseekdir(dhandle, 0); >+ torture_assert_int_equal_goto(tctx, >+ ret, >+ 0, >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "failed to seek directory handle to start for '%s'", >+ dname)); >+ >+ /* >+ * Mix getdents/readdir/readdirplus with lseek to ensure >+ * we get the same result. >+ */ >+ >+ /* Allocate the space for 20 entries. >+ * Tricky as we need to allocate 20 struct smbc_dirent's + space >+ * for the name lengths. >+ */ >+ getdentries_size = 20 * (sizeof(struct smbc_dirent) + >+ strlen("test_readdirplus_1000.txt") + 1); >+ >+ getdentries = (struct smbc_dirent *)talloc_array_size(tctx, >+ getdentries_size, >+ 1); >+ >+ ret = smbc_getdents(dhandle, getdentries, getdentries_size); >+ torture_assert_goto(tctx, >+ (ret != -1), >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "smbd_getdents(1) for '%s' failed\n", >+ dname)); >+ >+ telldir_20 = smbc_telldir(dhandle); >+ if (telldir_20 == (off_t)-1) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "telldir (20) failed\n")); >+ } >+ /* Read another 20. */ >+ ret = smbc_getdents(dhandle, getdentries, getdentries_size); >+ torture_assert_goto(tctx, >+ (ret != -1), >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "smbd_getdents(2) for '%s' failed\n", >+ dname)); >+ >+ /* Seek back to 20. */ >+ ret = smbc_lseekdir(dhandle, telldir_20); >+ torture_assert_int_equal_goto(tctx, >+ ret, >+ 0, >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "failed to seek (20) directory handle for '%s'", >+ dname)); >+ >+ /* Read with readdir. */ >+ dirent_20 = smbc_readdir(dhandle); >+ if (dirent_20 == NULL) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "smbc_readdir (20) failed\n")); >+ } >+ >+ /* Ensure the getdents and readdir names are the same. */ >+ ret = strcmp(dirent_20->name, getdentries[0].name); >+ if (ret != 0) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "after seek (20) readdir name missmatch " >+ "file %s - got %s\n", >+ dirent_20->name, >+ getdentries[0].name)); >+ } >+ >+ /* Seek back to 20. */ >+ ret = smbc_lseekdir(dhandle, telldir_20); >+ torture_assert_int_equal_goto(tctx, >+ ret, >+ 0, >+ success, >+ done, >+ talloc_asprintf(tctx, >+ "failed to seek (20) directory handle for '%s'", >+ dname)); >+ /* Read with readdirplus. */ >+ direntries_20 = smbc_readdirplus(dhandle); >+ if (direntries_20 == NULL) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "smbc_readdirplus (20) failed\n")); >+ } >+ >+ /* Ensure the readdirplus and readdir names are the same. */ >+ ret = strcmp(dirent_20->name, direntries_20->name); >+ if (ret != 0) { >+ torture_fail_goto(tctx, >+ done, >+ talloc_asprintf(tctx, >+ "after seek (20) readdirplus name missmatch " >+ "file %s - got %s\n", >+ dirent_20->name, >+ direntries_20->name)); >+ } >+ >+ ret = smbc_closedir(dhandle); >+ torture_assert_int_equal(tctx, >+ ret, >+ 0, >+ talloc_asprintf(tctx, >+ "failed to close directory handle for '%s'", >+ dname)); >+ >+ dhandle = -1; >+ success = true; >+ >+ done: >+ >+ /* Clean up. */ >+ if (dhandle != -1) { >+ smbc_closedir(dhandle); >+ } >+ for (i = 0; i < 100; i++) { >+ if (full_filename[i] != NULL) { >+ smbc_unlink(full_filename[i]); >+ } >+ } >+ if (dname != NULL) { >+ smbc_rmdir(dname); >+ } >+ >+ smbc_free_context(ctx, 1); >+ >+ return success; >+} >+ > bool torture_libsmbclient_configuration(struct torture_context *tctx) > { > SMBCCTX *ctx; >@@ -635,6 +973,8 @@ NTSTATUS torture_libsmbclient_init(TALLOC_CTX *ctx) > torture_suite_add_simple_test(suite, "list_shares", torture_libsmbclient_list_shares); > torture_suite_add_simple_test(suite, "readdirplus", > torture_libsmbclient_readdirplus); >+ torture_suite_add_simple_test(suite, "readdirplus_seek", >+ torture_libsmbclient_readdirplus_seek); > > suite->description = talloc_strdup(suite, "libsmbclient interface tests"); > >-- >2.17.1 > > >From 4d41dc32653bd1ae7d87dcd5779c3586ae6561d3 Mon Sep 17 00:00:00 2001 >From: Bryan Mason <bmason@redhat.com> >Date: Mon, 16 Sep 2019 12:35:06 -0700 >Subject: [PATCH 200/376] s3:client:Use DEVICE_URI, instead of argv[0],for > Device URI > >CUPS sanitizes argv[0] by removing username/password, so use >DEVICE_URI environment variable first. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14128 > >Signed-off-by: Bryan Mason <bmason@redhat.com> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Wed Sep 18 12:31:11 UTC 2019 on sn-devel-184 > >(cherry picked from commit d65b17c3f7f9959ed95b03cc09e020d7387b7931) >--- > source3/client/smbspool.c | 16 +++++++++------- > 1 file changed, 9 insertions(+), 7 deletions(-) > >diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c >index ad988eb0df9..36f7f67ca94 100644 >--- a/source3/client/smbspool.c >+++ b/source3/client/smbspool.c >@@ -256,13 +256,15 @@ main(int argc, /* I - Number of command-line arguments */ > > /* > * Find the URI ... >- */ >- if (dev_uri == NULL) { >- env = getenv("DEVICE_URI"); >- if (env != NULL && env[0] != '\0') { >- dev_uri = env; >- } >- } >+ * >+ * The URI in argv[0] is sanitized to remove username/password, so >+ * use DEVICE_URI if available. Otherwise keep the URI already >+ * discovered in argv. >+ */ >+ env = getenv("DEVICE_URI"); >+ if (env != NULL && env[0] != '\0') { >+ dev_uri = env; >+ } > > if (dev_uri == NULL) { > fprintf(stderr, >-- >2.17.1 > > >From 361f4f5d24721d54558144a5905657d5cc7281a3 Mon Sep 17 00:00:00 2001 >From: Martin Schwenke <martin@meltin.net> >Date: Tue, 13 Aug 2019 21:42:15 +1000 >Subject: [PATCH 201/376] ctdb-tools: Stop deleted nodes from influencing ctdb > nodestatus exit code > >Deleted nodes should simply be ignored. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14129 >RN: Stop deleted nodes from influencing ctdb nodestatus exit code > >Signed-off-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit 32b5ceb31936ec5447362236c1809db003561d29) >--- > ctdb/tools/ctdb.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > >diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c >index 2cc72eedc76..6a15b61ccd1 100644 >--- a/ctdb/tools/ctdb.c >+++ b/ctdb/tools/ctdb.c >@@ -5611,7 +5611,13 @@ static int control_nodestatus(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, > > ret = 0; > for (i=0; i<nodemap->num; i++) { >- ret |= nodemap->node[i].flags; >+ uint32_t flags = nodemap->node[i].flags; >+ >+ if ((flags & NODE_FLAGS_DELETED) != 0) { >+ continue; >+ } >+ >+ ret |= flags; > } > > return ret; >-- >2.17.1 > > >From d42c7ffa6cbd90d0e777e39b12eda5c69e186a2f Mon Sep 17 00:00:00 2001 >From: Mathieu Parent <math.parent@gmail.com> >Date: Wed, 18 Sep 2019 03:15:47 +0000 >Subject: [PATCH 202/376] pod2man is no longer needed > >Since e24e344d0da58013fd5fa404529fe1d25ef403bf. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14131 > >Signed-off-by: Mathieu Parent <math.parent@gmail.com> >Reviewed-by: Martin Schwenke <martin@meltin.net> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 8df123e7f7cb591f6673ccffefffc30b946f1a5b) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Fri Sep 20 21:13:55 UTC 2019 on sn-devel-184 >--- > pidl/wscript | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/pidl/wscript b/pidl/wscript >index 01b71bd8b27..d1b8278990a 100644 >--- a/pidl/wscript >+++ b/pidl/wscript >@@ -34,7 +34,6 @@ def configure(conf): > > # yapp is used for building the parser > conf.find_program('yapp', var='YAPP') >- conf.find_program('pod2man', var='POD2MAN') > > def build(bld): > >-- >2.17.1 > > >From 18963e909d75785b27ea2fd0323fa8514b3e3198 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Sat, 21 Sep 2019 13:24:59 +0200 >Subject: [PATCH 203/376] classicupgrade: fix a a bytes-like object is > required, not 'str' error >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14136 > >Signed-off-by: Bjoern Jacke <bjacke@samba.org> >Reviewed-by: Björn Baumbach <bb@samba.org> > >Autobuild-User(master): Björn Jacke <bjacke@samba.org> >Autobuild-Date(master): Mon Sep 23 12:58:20 UTC 2019 on sn-devel-184 > >(cherry picked from commit 465e518d6cc200eefa38643e720ce64e53abac2e) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Tue Sep 24 18:30:08 UTC 2019 on sn-devel-184 >--- > python/samba/upgrade.py | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/python/samba/upgrade.py b/python/samba/upgrade.py >index 12555b7994e..8511bed2868 100644 >--- a/python/samba/upgrade.py >+++ b/python/samba/upgrade.py >@@ -474,7 +474,7 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, > ldappass = secrets_db.get_ldap_bind_pw(ldapuser) > if ldappass is None: > raise ProvisioningError("ldapsam passdb backend detected but no LDAP Bind PW found in secrets.tdb for user %s. Please point this tool at the secrets.tdb that was used by the previous installation.") >- ldappass = ldappass.strip('\x00') >+ ldappass = ldappass.decode('utf-8').strip('\x00') > ldap = True > else: > ldapuser = None >-- >2.17.1 > > >From fa63860f7b1621e507c1950872444d366891384a Mon Sep 17 00:00:00 2001 >From: Noel Power <noel.power@suse.com> >Date: Thu, 8 Aug 2019 15:06:28 +0100 >Subject: [PATCH 204/376] s3/libads: clang: Fix Value stored to 'canon_princ' > is never read > >Fixes: > >source3/libads/kerberos.c:192:2: warning: Value stored to 'canon_princ' is never read <--[clang] > canon_princ = me; > ^ ~~ >1 warning generated. > >Signed-off-by: Noel Power <noel.power@suse.com> >Reviewed-by: Gary Lockyer <gary@catalyst.net.nz> >(cherry picked from commit 52d20087f620704549f5a5cdcbec79cb08a36290) >--- > source3/libads/kerberos.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c >index 721c3c2a929..9fbe7dd0f07 100644 >--- a/source3/libads/kerberos.c >+++ b/source3/libads/kerberos.c >@@ -189,9 +189,10 @@ int kerberos_kinit_password_ext(const char *principal, > goto out; > } > >- canon_princ = me; > #ifndef SAMBA4_USES_HEIMDAL /* MIT */ > canon_princ = my_creds.client; >+#else >+ canon_princ = me; > #endif /* MIT */ > > if ((code = krb5_cc_initialize(ctx, cc, canon_princ))) { >-- >2.17.1 > > >From ed3ac77dc22572132667df2f2ba717cc16a8daa7 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 13:58:46 +0200 >Subject: [PATCH 205/376] nsswitch: add logging to > wbc_auth_error_to_pam_error() for non auth errors > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit acbf922fc2963a42d6cbe652bb32eee231020958) >--- > nsswitch/pam_winbind.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/nsswitch/pam_winbind.c b/nsswitch/pam_winbind.c >index 7841377fdd6..3ad70d3c4cd 100644 >--- a/nsswitch/pam_winbind.c >+++ b/nsswitch/pam_winbind.c >@@ -862,6 +862,10 @@ static int wbc_auth_error_to_pam_error(struct pwb_context *ctx, > } > > ret = wbc_error_to_pam_error(status); >+ _pam_log(ctx, LOG_ERR, >+ "request %s failed: %s, PAM error: %s (%d)!", >+ fn, wbcErrorString(status), >+ _pam_error_code_str(ret), ret); > return pam_winbind_request_log(ctx, ret, username, fn); > } > >-- >2.17.1 > > >From 2ba8997d006eb6120ac3cf1917ba2b0e3b1a3d86 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 17 Sep 2019 08:05:09 +0200 >Subject: [PATCH 206/376] s4:auth: use the correct client realm in > gensec_gssapi_update_internal() > >The function gensec_gssapi_client_creds() may call kinit and gets >a TGT for the user. The principal provided by the user may not >be canonicalized. The user may use 'given.last@example.com' >but that may be mapped to glast@AD.EXAMPLE.PRIVATE in the background. > >It means we should use client_realm = AD.EXAMPLE.PRIVATE >instead of client_realm = EXAMPLE.COM > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit db8fd3d6a315b140ebd6ccd0dcdfdcf27cd1bb38) >--- > source4/auth/gensec/gensec_gssapi.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c >index 4577c91c93a..045a0225741 100644 >--- a/source4/auth/gensec/gensec_gssapi.c >+++ b/source4/auth/gensec/gensec_gssapi.c >@@ -437,8 +437,6 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec > const char *target_principal = gensec_get_target_principal(gensec_security); > const char *hostname = gensec_get_target_hostname(gensec_security); > const char *service = gensec_get_target_service(gensec_security); >- const char *client_realm = cli_credentials_get_realm(cli_creds); >- const char *server_realm = NULL; > gss_OID gss_oid_p = NULL; > OM_uint32 time_req = 0; > OM_uint32 time_rec = 0; >@@ -457,6 +455,7 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec > switch (gensec_security->gensec_role) { > case GENSEC_CLIENT: > { >+ const char *client_realm = NULL; > #ifdef SAMBA4_USES_HEIMDAL > struct gsskrb5_send_to_kdc send_to_kdc; > krb5_error_code ret; >@@ -532,6 +531,7 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec > * transitive forest trusts, would have to do the > * fallback ourself. > */ >+ client_realm = cli_credentials_get_realm(cli_creds); > #ifndef SAMBA4_USES_HEIMDAL > if (gensec_gssapi_state->server_name == NULL) { > nt_status = gensec_gssapi_setup_server_principal(gensec_gssapi_state, >@@ -575,6 +575,8 @@ static NTSTATUS gensec_gssapi_update_internal(struct gensec_security *gensec_sec > } > #endif /* !SAMBA4_USES_HEIMDAL */ > if (gensec_gssapi_state->server_name == NULL) { >+ const char *server_realm = NULL; >+ > server_realm = smb_krb5_get_realm_from_hostname(gensec_gssapi_state, > hostname, > client_realm); >-- >2.17.1 > > >From f5ea5a5e2a5479b993cea335b73194b1c4cc6e76 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 16 Sep 2019 17:14:11 +0200 >Subject: [PATCH 207/376] s3:libads: let kerberos_kinit_password_ext() return > the canonicalized principal/realm > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit bc473e5cf088a137395842540ed8eb748373a236) >--- > source3/libads/authdata.c | 1 + > source3/libads/kerberos.c | 46 ++++++++++++++++++++++---- > source3/libads/kerberos_proto.h | 5 ++- > source3/libads/kerberos_util.c | 3 +- > source3/utils/net_ads.c | 3 ++ > source3/winbindd/winbindd_cred_cache.c | 6 ++++ > 6 files changed, 56 insertions(+), 8 deletions(-) > >diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c >index 86a1be71bf9..6e6d5b397ff 100644 >--- a/source3/libads/authdata.c >+++ b/source3/libads/authdata.c >@@ -170,6 +170,7 @@ NTSTATUS kerberos_return_pac(TALLOC_CTX *mem_ctx, > request_pac, > add_netbios_addr, > renewable_time, >+ NULL, NULL, NULL, > &status); > if (ret) { > DEBUG(1,("kinit failed for '%s' with: %s (%d)\n", >diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c >index 9fbe7dd0f07..3e09d70268f 100644 >--- a/source3/libads/kerberos.c >+++ b/source3/libads/kerberos.c >@@ -106,7 +106,7 @@ kerb_prompter(krb5_context ctx, void *data, > place in default cache location. > remus@snapserver.com > */ >-int kerberos_kinit_password_ext(const char *principal, >+int kerberos_kinit_password_ext(const char *given_principal, > const char *password, > int time_offset, > time_t *expire_time, >@@ -115,8 +115,12 @@ int kerberos_kinit_password_ext(const char *principal, > bool request_pac, > bool add_netbios_addr, > time_t renewable_time, >+ TALLOC_CTX *mem_ctx, >+ char **_canon_principal, >+ char **_canon_realm, > NTSTATUS *ntstatus) > { >+ TALLOC_CTX *frame = talloc_stackframe(); > krb5_context ctx = NULL; > krb5_error_code code = 0; > krb5_ccache cc = NULL; >@@ -125,6 +129,8 @@ int kerberos_kinit_password_ext(const char *principal, > krb5_creds my_creds; > krb5_get_init_creds_opt *opt = NULL; > smb_krb5_addresses *addr = NULL; >+ char *canon_principal = NULL; >+ char *canon_realm = NULL; > > ZERO_STRUCT(my_creds); > >@@ -132,6 +138,7 @@ int kerberos_kinit_password_ext(const char *principal, > if (code != 0) { > DBG_ERR("kerberos init context failed (%s)\n", > error_message(code)); >+ TALLOC_FREE(frame); > return code; > } > >@@ -139,16 +146,16 @@ int kerberos_kinit_password_ext(const char *principal, > krb5_set_real_time(ctx, time(NULL) + time_offset, 0); > } > >- DEBUG(10,("kerberos_kinit_password: as %s using [%s] as ccache and config [%s]\n", >- principal, >- cache_name ? cache_name: krb5_cc_default_name(ctx), >- getenv("KRB5_CONFIG"))); >+ DBG_DEBUG("as %s using [%s] as ccache and config [%s]\n", >+ given_principal, >+ cache_name ? cache_name: krb5_cc_default_name(ctx), >+ getenv("KRB5_CONFIG")); > > if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) { > goto out; > } > >- if ((code = smb_krb5_parse_name(ctx, principal, &me))) { >+ if ((code = smb_krb5_parse_name(ctx, given_principal, &me))) { > goto out; > } > >@@ -195,6 +202,22 @@ int kerberos_kinit_password_ext(const char *principal, > canon_princ = me; > #endif /* MIT */ > >+ code = smb_krb5_unparse_name(frame, >+ ctx, >+ canon_princ, >+ &canon_principal); >+ if (code != 0) { >+ goto out; >+ } >+ >+ DBG_DEBUG("%s mapped to %s\n", given_principal, canon_principal); >+ >+ canon_realm = smb_krb5_principal_get_realm(frame, ctx, canon_princ); >+ if (canon_realm == NULL) { >+ code = ENOMEM; >+ goto out; >+ } >+ > if ((code = krb5_cc_initialize(ctx, cc, canon_princ))) { > goto out; > } >@@ -210,6 +233,13 @@ int kerberos_kinit_password_ext(const char *principal, > if (renew_till_time) { > *renew_till_time = (time_t) my_creds.times.renew_till; > } >+ >+ if (_canon_principal != NULL) { >+ *_canon_principal = talloc_move(mem_ctx, &canon_principal); >+ } >+ if (_canon_realm != NULL) { >+ *_canon_realm = talloc_move(mem_ctx, &canon_realm); >+ } > out: > if (ntstatus) { > /* fast path */ >@@ -239,6 +269,7 @@ int kerberos_kinit_password_ext(const char *principal, > if (ctx) { > krb5_free_context(ctx); > } >+ TALLOC_FREE(frame); > return code; > } > >@@ -328,6 +359,9 @@ int kerberos_kinit_password(const char *principal, > False, > False, > 0, >+ NULL, >+ NULL, >+ NULL, > NULL); > } > >diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h >index f92cabd757e..433bce9e0ec 100644 >--- a/source3/libads/kerberos_proto.h >+++ b/source3/libads/kerberos_proto.h >@@ -45,7 +45,7 @@ struct PAC_DATA_CTR { > > /* The following definitions come from libads/kerberos.c */ > >-int kerberos_kinit_password_ext(const char *principal, >+int kerberos_kinit_password_ext(const char *given_principal, > const char *password, > int time_offset, > time_t *expire_time, >@@ -54,6 +54,9 @@ int kerberos_kinit_password_ext(const char *principal, > bool request_pac, > bool add_netbios_addr, > time_t renewable_time, >+ TALLOC_CTX *mem_ctx, >+ char **_canon_principal, >+ char **_canon_realm, > NTSTATUS *ntstatus); > int ads_kdestroy(const char *cc_name); > >diff --git a/source3/libads/kerberos_util.c b/source3/libads/kerberos_util.c >index 68c0f302239..bfe53820aff 100644 >--- a/source3/libads/kerberos_util.c >+++ b/source3/libads/kerberos_util.c >@@ -66,7 +66,8 @@ int ads_kinit_password(ADS_STRUCT *ads) > ads->auth.time_offset, > &ads->auth.tgt_expire, NULL, > ads->auth.ccache_name, false, false, >- ads->auth.renewable, NULL); >+ ads->auth.renewable, >+ NULL, NULL, NULL, NULL); > > if (ret) { > DEBUG(0,("kerberos_kinit_password %s failed: %s\n", >diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c >index 6b4cd3591b0..4a0f59a1e80 100644 >--- a/source3/utils/net_ads.c >+++ b/source3/utils/net_ads.c >@@ -3353,6 +3353,9 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** > true, > true, > 2592000, /* one month */ >+ NULL, >+ NULL, >+ NULL, > &status); > if (ret) { > d_printf(_("failed to kinit password: %s\n"), >diff --git a/source3/winbindd/winbindd_cred_cache.c b/source3/winbindd/winbindd_cred_cache.c >index 85ad426446a..5baecf906b9 100644 >--- a/source3/winbindd/winbindd_cred_cache.c >+++ b/source3/winbindd/winbindd_cred_cache.c >@@ -146,6 +146,9 @@ rekinit: > False, /* no PAC required anymore */ > True, > WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, >+ NULL, >+ NULL, >+ NULL, > NULL); > gain_root_privilege(); > >@@ -343,6 +346,9 @@ static void krb5_ticket_gain_handler(struct tevent_context *event_ctx, > False, /* no PAC required anymore */ > True, > WINBINDD_PAM_AUTH_KRB5_RENEW_TIME, >+ NULL, >+ NULL, >+ NULL, > NULL); > gain_root_privilege(); > >-- >2.17.1 > > >From 7ed225544705ad3b6f66122fe335bb8e47569d95 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 17 Sep 2019 10:08:10 +0200 >Subject: [PATCH 208/376] s3:libsmb: avoid wrong debug message in > cli_session_creds_prepare_krb5() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 361fb0efabfb189526c851107eee49161da2293c) >--- > source3/libsmb/cliconnect.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c >index 3a116b6c7e6..7b6adfd6975 100644 >--- a/source3/libsmb/cliconnect.c >+++ b/source3/libsmb/cliconnect.c >@@ -375,6 +375,8 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > /* > * Ignore the error and hope that NTLM will work > */ >+ TALLOC_FREE(frame); >+ return NT_STATUS_OK; > } > > DBG_DEBUG("Successfully authenticated as %s to access %s using " >-- >2.17.1 > > >From 5628c4ffd328634014b5cc97f2717ff829bab8e3 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 17 Sep 2019 08:49:13 +0200 >Subject: [PATCH 209/376] s3:libsmb: let cli_session_creds_prepare_krb5() > update the canonicalized principal to cli_credentials > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 6ed18c12c57efb2a010e0ce5196c51b48e57a4b9) >--- > source3/libsmb/cliconnect.c | 39 ++++++++++++++++++++++++++++++++----- > 1 file changed, 34 insertions(+), 5 deletions(-) > >diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c >index 7b6adfd6975..94cec062881 100644 >--- a/source3/libsmb/cliconnect.c >+++ b/source3/libsmb/cliconnect.c >@@ -229,6 +229,8 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > const char *user_account = NULL; > const char *user_domain = NULL; > const char *pass = NULL; >+ char *canon_principal = NULL; >+ char *canon_realm = NULL; > const char *target_hostname = NULL; > const DATA_BLOB *server_blob = NULL; > bool got_kerberos_mechanism = false; >@@ -237,6 +239,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > bool need_kinit = false; > bool auth_requested = true; > int ret; >+ bool ok; > > target_hostname = smbXcli_conn_remote_name(cli->conn); > server_blob = smbXcli_conn_server_gss_blob(cli->conn); >@@ -245,7 +248,6 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > if (server_blob != NULL && server_blob->length != 0) { > char *OIDs[ASN1_MAX_OIDS] = { NULL, }; > size_t i; >- bool ok; > > /* > * The server sent us the first part of the SPNEGO exchange in the >@@ -354,9 +356,19 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > * only if required! > */ > setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); >- ret = kerberos_kinit_password(user_principal, pass, >- 0 /* no time correction for now */, >- NULL); >+ ret = kerberos_kinit_password_ext(user_principal, >+ pass, >+ 0, >+ 0, >+ 0, >+ NULL, >+ false, >+ false, >+ 0, >+ frame, >+ &canon_principal, >+ &canon_realm, >+ NULL); > if (ret != 0) { > int dbglvl = DBGLVL_NOTICE; > >@@ -379,9 +391,26 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, > return NT_STATUS_OK; > } > >- DBG_DEBUG("Successfully authenticated as %s to access %s using " >+ ok = cli_credentials_set_principal(creds, >+ canon_principal, >+ CRED_SPECIFIED); >+ if (!ok) { >+ TALLOC_FREE(frame); >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ ok = cli_credentials_set_realm(creds, >+ canon_realm, >+ CRED_SPECIFIED); >+ if (!ok) { >+ TALLOC_FREE(frame); >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ DBG_DEBUG("Successfully authenticated as %s (%s) to access %s using " > "Kerberos\n", > user_principal, >+ canon_principal, > target_hostname); > > TALLOC_FREE(frame); >-- >2.17.1 > > >From 35e3f1a4054dd55e53e229fd78fe85433f577d95 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 13 Sep 2019 16:04:30 +0200 >Subject: [PATCH 210/376] s3:libads/kerberos: always use the canonicalized > principal after kinit > >We should always use krb5_get_init_creds_opt_set_canonicalize() >and krb5_get_init_creds_opt_set_win2k() for heimdal >and expect the client principal to be changed. > >There's no reason to have a different logic between MIT and Heimdal. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 0bced73bed481a8846a6b3e68be85941914390ba) >--- > source3/libads/kerberos.c | 9 ++++----- > 1 file changed, 4 insertions(+), 5 deletions(-) > >diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c >index 3e09d70268f..559ec3b7f53 100644 >--- a/source3/libads/kerberos.c >+++ b/source3/libads/kerberos.c >@@ -167,7 +167,10 @@ int kerberos_kinit_password_ext(const char *given_principal, > krb5_get_init_creds_opt_set_forwardable(opt, True); > > /* Turn on canonicalization for lower case realm support */ >-#ifndef SAMBA4_USES_HEIMDAL /* MIT */ >+#ifdef SAMBA4_USES_HEIMDAL >+ krb5_get_init_creds_opt_set_win2k(ctx, opt, true); >+ krb5_get_init_creds_opt_set_canonicalize(ctx, opt, true); >+#else /* MIT */ > krb5_get_init_creds_opt_set_canonicalize(opt, true); > #endif /* MIT */ > #if 0 >@@ -196,11 +199,7 @@ int kerberos_kinit_password_ext(const char *given_principal, > goto out; > } > >-#ifndef SAMBA4_USES_HEIMDAL /* MIT */ > canon_princ = my_creds.client; >-#else >- canon_princ = me; >-#endif /* MIT */ > > code = smb_krb5_unparse_name(frame, > ctx, >-- >2.17.1 > > >From d3d951f4240c543162976e18da9e0090254d72b6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 13 Sep 2019 16:04:30 +0200 >Subject: [PATCH 211/376] krb5_wrap: smb_krb5_kinit_password_ccache() should > always use the canonicalized principal > >We should always use krb5_get_init_creds_opt_set_canonicalize() >and krb5_get_init_creds_opt_set_win2k() for heimdal >and expect the client principal to be changed. > >There's no reason to have a different logic between MIT and Heimdal. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 5d0bf32ec0ad21d49587e3a1520ffdc8b5ae7614) >--- > lib/krb5_wrap/krb5_samba.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 72889fffcf0..55c17d481f4 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -2114,14 +2114,12 @@ krb5_error_code smb_krb5_kinit_password_ccache(krb5_context ctx, > return code; > } > >-#ifndef SAMBA4_USES_HEIMDAL /* MIT */ > /* > * We need to store the principal as returned from the KDC to the > * credentials cache. If we don't do that the KRB5 library is not > * able to find the tickets it is looking for > */ > principal = my_creds.client; >-#endif > code = krb5_cc_initialize(ctx, cc, principal); > if (code) { > goto done; >-- >2.17.1 > > >From 5d9961e64542ff1a7d360441db62ef6af3118292 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 13 Sep 2019 16:04:30 +0200 >Subject: [PATCH 212/376] s4:auth: kinit_to_ccache() should always use the > canonicalized principal > >We should always use krb5_get_init_creds_opt_set_canonicalize() >and krb5_get_init_creds_opt_set_win2k() for heimdal >and expect the client principal to be changed. > >There's no reason to have a different logic between MIT and Heimdal. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 162b4199493c1f179e775a325a19ae7a136c418b) >--- > source4/auth/kerberos/kerberos_util.c | 2 ++ > 1 file changed, 2 insertions(+) > >diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c >index 50bf8feec96..950d91f1737 100644 >--- a/source4/auth/kerberos/kerberos_util.c >+++ b/source4/auth/kerberos/kerberos_util.c >@@ -313,6 +313,8 @@ done: > */ > krb5_get_init_creds_opt_set_win2k(smb_krb5_context->krb5_context, > krb_options, true); >+ krb5_get_init_creds_opt_set_canonicalize(smb_krb5_context->krb5_context, >+ krb_options, true); > #else /* MIT */ > krb5_get_init_creds_opt_set_canonicalize(krb_options, true); > #endif >-- >2.17.1 > > >From 2fd31d85701a4f05c306eb47791c65fd7e39d66d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 13 Sep 2019 16:04:30 +0200 >Subject: [PATCH 213/376] s3:libads: ads_krb5_chg_password() should always use > the canonicalized principal > >We should always use krb5_get_init_creds_opt_set_canonicalize() >and krb5_get_init_creds_opt_set_win2k() for heimdal >and expect the client principal to be changed. > >There's no reason to have a different logic between MIT and Heimdal. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 303b7e59a286896888ee2473995fc50bb2b5ce5e) >--- > source3/libads/krb5_setpw.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c >index c3c9477c4cf..67bc2f4640d 100644 >--- a/source3/libads/krb5_setpw.c >+++ b/source3/libads/krb5_setpw.c >@@ -203,6 +203,12 @@ static ADS_STATUS ads_krb5_chg_password(const char *kdc_host, > krb5_get_init_creds_opt_set_renew_life(opts, 0); > krb5_get_init_creds_opt_set_forwardable(opts, 0); > krb5_get_init_creds_opt_set_proxiable(opts, 0); >+#ifdef SAMBA4_USES_HEIMDAL >+ krb5_get_init_creds_opt_set_win2k(context, opts, true); >+ krb5_get_init_creds_opt_set_canonicalize(context, opts, true); >+#else /* MIT */ >+ krb5_get_init_creds_opt_set_canonicalize(opts, true); >+#endif /* MIT */ > > /* note that heimdal will fill in the local addresses if the addresses > * in the creds_init_opt are all empty and then later fail with invalid >-- >2.17.1 > > >From 9de64feb1ec94ccef89931ce41ffebb18d80d921 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 13 Sep 2019 15:52:25 +0200 >Subject: [PATCH 214/376] krb5_wrap: let smb_krb5_parse_name() accept > enterprise principals > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 3bdf023956e861485be70430112ed38d0a5424f7) >--- > lib/krb5_wrap/krb5_samba.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/lib/krb5_wrap/krb5_samba.c b/lib/krb5_wrap/krb5_samba.c >index 55c17d481f4..a4e73c64f00 100644 >--- a/lib/krb5_wrap/krb5_samba.c >+++ b/lib/krb5_wrap/krb5_samba.c >@@ -701,6 +701,11 @@ krb5_error_code smb_krb5_parse_name(krb5_context context, > } > > ret = krb5_parse_name(context, utf8_name, principal); >+ if (ret == KRB5_PARSE_MALFORMED) { >+ ret = krb5_parse_name_flags(context, utf8_name, >+ KRB5_PRINCIPAL_PARSE_ENTERPRISE, >+ principal); >+ } > TALLOC_FREE(frame); > return ret; > } >-- >2.17.1 > > >From 82fb0291f1fe69143b093a4b3cb47fc36d964c22 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 11 Sep 2019 16:44:43 +0200 >Subject: [PATCH 215/376] docs-xml: add "winbind use krb5 enterprise > principals" option > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 9520652399696010c333a3ce7247809ce5337a91) >--- > .../winbindusekrb5enterpriseprincipals.xml | 34 +++++++++++++++++++ > 1 file changed, 34 insertions(+) > create mode 100644 docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml > >diff --git a/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml b/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml >new file mode 100644 >index 00000000000..bfc11c8636c >--- /dev/null >+++ b/docs-xml/smbdotconf/winbind/winbindusekrb5enterpriseprincipals.xml >@@ -0,0 +1,34 @@ >+<samba:parameter name="winbind use krb5 enterprise principals" >+ context="G" >+ type="boolean" >+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> >+<description> >+ <para>winbindd is able to get kerberos tickets for >+ pam_winbind with krb5_auth or wbinfo -K/--krb5auth=. >+ </para> >+ >+ <para>winbindd (at least on a domain member) is never be able >+ to have a complete picture of the trust topology (which is managed by the DCs). >+ There might be uPNSuffixes and msDS-SPNSuffixes values, >+ which don't belong to any AD domain at all. >+ </para> >+ >+ <para>With <smbconfoption name="winbind scan trusted domains">no</smbconfoption> >+ winbindd don't even get an incomplete picture of the topology. >+ </para> >+ >+ <para>It is not really required to know about the trust topology. >+ We can just rely on the [K]DCs of our primary domain (e.g. PRIMARY.A.EXAMPLE.COM) >+ and use enterprise principals e.g. upnfromB@B.EXAMPLE.COM@PRIMARY.A.EXAMPLE.COM >+ and follow the WRONG_REALM referrals in order to find the correct DC. >+ The final principal might be userfromB@INTERNALB.EXAMPLE.PRIVATE. >+ </para> >+ >+ <para>With <smbconfoption name="winbind use krb5 enterprise principals">yes</smbconfoption> >+ winbindd enterprise principals will be used. >+ </para> >+</description> >+ >+<value type="default">no</value> >+<value type="example">yes</value> >+</samba:parameter> >-- >2.17.1 > > >From e8c701673a8b0378e95f501c5ccb4f3cb661460e Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 19 Jul 2019 15:10:09 +0000 >Subject: [PATCH 216/376] s3:winbindd: implement the "winbind use krb5 > enterprise principals" logic > >We can use enterprise principals (e.g. upnfromB@B.EXAMPLE.COM@PRIMARY.A.EXAMPLE.COM) >and delegate the routing decisions to the KDCs. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit a77be15d28390c5d12202278adbe6b50200a2c1b) >--- > source3/winbindd/winbindd_pam.c | 57 +++++++++++++++++++-------------- > 1 file changed, 33 insertions(+), 24 deletions(-) > >diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c >index eaf16d0dced..c5b7c09b5c1 100644 >--- a/source3/winbindd/winbindd_pam.c >+++ b/source3/winbindd/winbindd_pam.c >@@ -419,6 +419,15 @@ struct winbindd_domain *find_auth_domain(uint8_t flags, > return find_domain_from_name_noinit(domain_name); > } > >+ if (lp_winbind_use_krb5_enterprise_principals()) { >+ /* >+ * If we use enterprise principals >+ * we always go trough our primary domain >+ * and follow the WRONG_REALM replies. >+ */ >+ flags &= ~WBFLAG_PAM_CONTACT_TRUSTDOM; >+ } >+ > /* we can auth against trusted domains */ > if (flags & WBFLAG_PAM_CONTACT_TRUSTDOM) { > domain = find_domain_from_name_noinit(domain_name); >@@ -723,7 +732,20 @@ static NTSTATUS winbindd_raw_kerberos_login(TALLOC_CTX *mem_ctx, > return NT_STATUS_INVALID_PARAMETER; > } > >- principal_s = talloc_asprintf(mem_ctx, "%s@%s", name_user, realm); >+ if (lp_winbind_use_krb5_enterprise_principals() && >+ name_namespace[0] != '\0') >+ { >+ principal_s = talloc_asprintf(mem_ctx, >+ "%s@%s@%s", >+ name_user, >+ name_namespace, >+ realm); >+ } else { >+ principal_s = talloc_asprintf(mem_ctx, >+ "%s@%s", >+ name_user, >+ realm); >+ } > if (principal_s == NULL) { > return NT_STATUS_NO_MEMORY; > } >@@ -1290,30 +1312,16 @@ static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, > > /* what domain should we contact? */ > >- if ( IS_DC ) { >- contact_domain = find_domain_from_name(name_namespace); >- if (contact_domain == NULL) { >- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", >- state->request->data.auth.user, name_domain, name_user, name_domain)); >- result = NT_STATUS_NO_SUCH_USER; >- goto done; >- } >- >+ if (lp_winbind_use_krb5_enterprise_principals()) { >+ contact_domain = find_auth_domain(0, name_namespace); > } else { >- if (is_myname(name_domain)) { >- DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain)); >- result = NT_STATUS_NO_SUCH_USER; >- goto done; >- } >- > contact_domain = find_domain_from_name(name_namespace); >- if (contact_domain == NULL) { >- DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", >- state->request->data.auth.user, name_domain, name_user, name_domain)); >- >- result = NT_STATUS_NO_SUCH_USER; >- goto done; >- } >+ } >+ if (contact_domain == NULL) { >+ DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", >+ state->request->data.auth.user, name_domain, name_user, name_namespace)); >+ result = NT_STATUS_NO_SUCH_USER; >+ goto done; > } > > if (contact_domain->initialized && >@@ -1326,7 +1334,8 @@ static NTSTATUS winbindd_dual_pam_auth_kerberos(struct winbindd_domain *domain, > } > > if (!contact_domain->active_directory) { >- DEBUG(3,("krb5 auth requested but domain is not Active Directory\n")); >+ DEBUG(3,("krb5 auth requested but domain (%s) is not Active Directory\n", >+ contact_domain->name)); > return NT_STATUS_INVALID_LOGON_TYPE; > } > try_login: >-- >2.17.1 > > >From 5583d045a259a54f3f9000e747a713fa97effe15 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 08:04:42 +0200 >Subject: [PATCH 217/376] tests/pam_winbind.py: turn pypamtest.PamTestError > into a failure > >A failure generated by the AssertionError() checks can be added >to selftest/knownfail.d/*. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit cd3ffaabb568db26e0de5e83178487e5947c4f09) >--- > python/samba/tests/pam_winbind.py | 15 ++++++++++++--- > python/samba/tests/pam_winbind_chauthtok.py | 5 ++++- > python/samba/tests/pam_winbind_warn_pwd_expire.py | 5 ++++- > 3 files changed, 20 insertions(+), 5 deletions(-) > >diff --git a/python/samba/tests/pam_winbind.py b/python/samba/tests/pam_winbind.py >index 68b05b30d7d..b05e8af6ffb 100644 >--- a/python/samba/tests/pam_winbind.py >+++ b/python/samba/tests/pam_winbind.py >@@ -30,7 +30,10 @@ class SimplePamTests(samba.tests.TestCase): > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >- res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ try: >+ res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ except pypamtest.PamTestError as e: >+ raise AssertionError(str(e)) > > self.assertTrue(res is not None) > >@@ -42,7 +45,10 @@ class SimplePamTests(samba.tests.TestCase): > expected_rc = 7 # PAM_AUTH_ERR > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >- res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ try: >+ res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ except pypamtest.PamTestError as e: >+ raise AssertionError(str(e)) > > self.assertTrue(res is not None) > >@@ -52,6 +58,9 @@ class SimplePamTests(samba.tests.TestCase): > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >- res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ try: >+ res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ except pypamtest.PamTestError as e: >+ raise AssertionError(str(e)) > > self.assertTrue(res is not None) >diff --git a/python/samba/tests/pam_winbind_chauthtok.py b/python/samba/tests/pam_winbind_chauthtok.py >index e5be3a83ce7..18c2705127a 100644 >--- a/python/samba/tests/pam_winbind_chauthtok.py >+++ b/python/samba/tests/pam_winbind_chauthtok.py >@@ -31,6 +31,9 @@ class PamChauthtokTests(samba.tests.TestCase): > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_CHAUTHTOK, expected_rc) >- res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password, newpassword, newpassword]) >+ try: >+ res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password, newpassword, newpassword]) >+ except pypamtest.PamTestError as e: >+ raise AssertionError(str(e)) > > self.assertTrue(res is not None) >diff --git a/python/samba/tests/pam_winbind_warn_pwd_expire.py b/python/samba/tests/pam_winbind_warn_pwd_expire.py >index df60bc5ace6..1af2f9befe1 100644 >--- a/python/samba/tests/pam_winbind_warn_pwd_expire.py >+++ b/python/samba/tests/pam_winbind_warn_pwd_expire.py >@@ -31,7 +31,10 @@ class PasswordExpirePamTests(samba.tests.TestCase): > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >- res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ try: >+ res = pypamtest.run_pamtest(unix_username, "samba", [tc], [password]) >+ except pypamtest.PamTestError as e: >+ raise AssertionError(str(e)) > > self.assertTrue(res is not None) > if warn_pwd_expire == 0: >-- >2.17.1 > > >From 913c79d2e06acf93b7a3fedab6b0c30a0c1272bf Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 20 Sep 2019 08:13:28 +0200 >Subject: [PATCH 218/376] tests/pam_winbind.py: allow upn names to be used in > USERNAME with an empty DOMAIN value > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 653e90485854d978dc522e689cd78c19dcc22a70) >--- > python/samba/tests/pam_winbind.py | 10 ++++++++-- > python/samba/tests/pam_winbind_chauthtok.py | 5 ++++- > python/samba/tests/pam_winbind_warn_pwd_expire.py | 5 ++++- > 3 files changed, 16 insertions(+), 4 deletions(-) > >diff --git a/python/samba/tests/pam_winbind.py b/python/samba/tests/pam_winbind.py >index b05e8af6ffb..708f408f768 100644 >--- a/python/samba/tests/pam_winbind.py >+++ b/python/samba/tests/pam_winbind.py >@@ -26,7 +26,10 @@ class SimplePamTests(samba.tests.TestCase): > domain = os.environ["DOMAIN"] > username = os.environ["USERNAME"] > password = os.environ["PASSWORD"] >- unix_username = "%s/%s" % (domain, username) >+ if domain != "": >+ unix_username = "%s/%s" % (domain, username) >+ else: >+ unix_username = "%s" % username > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >@@ -41,7 +44,10 @@ class SimplePamTests(samba.tests.TestCase): > domain = os.environ["DOMAIN"] > username = os.environ["USERNAME"] > password = "WrongPassword" >- unix_username = "%s/%s" % (domain, username) >+ if domain != "": >+ unix_username = "%s/%s" % (domain, username) >+ else: >+ unix_username = "%s" % username > expected_rc = 7 # PAM_AUTH_ERR > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >diff --git a/python/samba/tests/pam_winbind_chauthtok.py b/python/samba/tests/pam_winbind_chauthtok.py >index 18c2705127a..c1d569b3cd0 100644 >--- a/python/samba/tests/pam_winbind_chauthtok.py >+++ b/python/samba/tests/pam_winbind_chauthtok.py >@@ -27,7 +27,10 @@ class PamChauthtokTests(samba.tests.TestCase): > username = os.environ["USERNAME"] > password = os.environ["PASSWORD"] > newpassword = os.environ["NEWPASSWORD"] >- unix_username = "%s/%s" % (domain, username) >+ if domain != "": >+ unix_username = "%s/%s" % (domain, username) >+ else: >+ unix_username = "%s" % username > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_CHAUTHTOK, expected_rc) >diff --git a/python/samba/tests/pam_winbind_warn_pwd_expire.py b/python/samba/tests/pam_winbind_warn_pwd_expire.py >index 1af2f9befe1..56f5da94f98 100644 >--- a/python/samba/tests/pam_winbind_warn_pwd_expire.py >+++ b/python/samba/tests/pam_winbind_warn_pwd_expire.py >@@ -27,7 +27,10 @@ class PasswordExpirePamTests(samba.tests.TestCase): > username = os.environ["USERNAME"] > password = os.environ["PASSWORD"] > warn_pwd_expire = int(os.environ["WARN_PWD_EXPIRE"]) >- unix_username = "%s/%s" % (domain, username) >+ if domain != "": >+ unix_username = "%s/%s" % (domain, username) >+ else: >+ unix_username = "%s" % username > expected_rc = 0 # PAM_SUCCESS > > tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE, expected_rc) >-- >2.17.1 > > >From 8aae6dd753b51bc54042c8cbc9308e08cdeef089 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 01:25:58 +0200 >Subject: [PATCH 219/376] test_pam_winbind.sh: allow different pam_winbindd > config options to be specified > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 3d38a8e9135bb72bc4ca079fab0eb5358942b3f1) >--- > python/samba/tests/test_pam_winbind.sh | 12 +++++++---- > .../samba/tests/test_pam_winbind_chauthtok.sh | 4 ++-- > .../tests/test_pam_winbind_warn_pwd_expire.sh | 20 +++++++++++-------- > selftest/tests.py | 6 +++--- > 4 files changed, 25 insertions(+), 17 deletions(-) > >diff --git a/python/samba/tests/test_pam_winbind.sh b/python/samba/tests/test_pam_winbind.sh >index 0406b108b31..755e67280fa 100755 >--- a/python/samba/tests/test_pam_winbind.sh >+++ b/python/samba/tests/test_pam_winbind.sh >@@ -12,6 +12,10 @@ PASSWORD="$3" > export PASSWORD > shift 3 > >+PAM_OPTIONS="$1" >+export PAM_OPTIONS >+shift 1 >+ > PAM_WRAPPER_PATH="$BINDIR/default/third_party/pam_wrapper" > > pam_winbind="$BINDIR/shared/pam_winbind.so" >@@ -19,10 +23,10 @@ service_dir="$SELFTEST_TMPDIR/pam_services" > service_file="$service_dir/samba" > > mkdir $service_dir >-echo "auth required $pam_winbind debug debug_state" > $service_file >-echo "account required $pam_winbind debug debug_state" >> $service_file >-echo "password required $pam_winbind debug debug_state" >> $service_file >-echo "session required $pam_winbind debug debug_state" >> $service_file >+echo "auth required $pam_winbind debug debug_state $PAM_OPTIONS" > $service_file >+echo "account required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file >+echo "password required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file >+echo "session required $pam_winbind debug debug_state $PAM_OPTIONS" >> $service_file > > PAM_WRAPPER="1" > export PAM_WRAPPER >diff --git a/python/samba/tests/test_pam_winbind_chauthtok.sh b/python/samba/tests/test_pam_winbind_chauthtok.sh >index 5887699300a..48adc81859d 100755 >--- a/python/samba/tests/test_pam_winbind_chauthtok.sh >+++ b/python/samba/tests/test_pam_winbind_chauthtok.sh >@@ -53,11 +53,11 @@ PAM_WRAPPER_DEBUGLEVEL=${PAM_WRAPPER_DEBUGLEVEL:="2"} > export PAM_WRAPPER_DEBUGLEVEL > > case $PAM_OPTIONS in >- use_authtok) >+ *use_authtok*) > PAM_AUTHTOK="$NEWPASSWORD" > export PAM_AUTHTOK > ;; >- try_authtok) >+ *try_authtok*) > PAM_AUTHTOK="$NEWPASSWORD" > export PAM_AUTHTOK > ;; >diff --git a/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh >index 16dede44227..348d2ae8387 100755 >--- a/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh >+++ b/python/samba/tests/test_pam_winbind_warn_pwd_expire.sh >@@ -12,6 +12,10 @@ PASSWORD="$3" > export PASSWORD > shift 3 > >+PAM_OPTIONS="$1" >+export PAM_OPTIONS >+shift 1 >+ > PAM_WRAPPER_PATH="$BINDIR/default/third_party/pam_wrapper" > > pam_winbind="$BINDIR/shared/pam_winbind.so" >@@ -37,10 +41,10 @@ export PAM_WRAPPER_DEBUGLEVEL > WARN_PWD_EXPIRE="50" > export WARN_PWD_EXPIRE > >-echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" > $service_file >-echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >-echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >-echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >+echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" > $service_file >+echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file >+echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file >+echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file > > PYTHONPATH="$PYTHONPATH:$PAM_WRAPPER_PATH:$(dirname $0)" $PYTHON -m samba.subunit.run samba.tests.pam_winbind_warn_pwd_expire > exit_code=$? >@@ -54,10 +58,10 @@ fi > WARN_PWD_EXPIRE="0" > export WARN_PWD_EXPIRE > >-echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" > $service_file >-echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >-echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >-echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE" >> $service_file >+echo "auth required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" > $service_file >+echo "account required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file >+echo "password required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file >+echo "session required $pam_winbind debug debug_state warn_pwd_expire=$WARN_PWD_EXPIRE $PAM_OPTIONS" >> $service_file > > PYTHONPATH="$PYTHONPATH:$PAM_WRAPPER_PATH:$(dirname $0)" $PYTHON -m samba.subunit.run samba.tests.pam_winbind_warn_pwd_expire > exit_code=$? >diff --git a/selftest/tests.py b/selftest/tests.py >index 1568f29b212..2d3587837a3 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -216,11 +216,11 @@ if with_pam: > plantestsuite("samba.tests.pam_winbind(local)", "ad_member", > [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), > valgrindify(python), pam_wrapper_so_path, >- "$SERVER", "$USERNAME", "$PASSWORD"]) >+ "$SERVER", "$USERNAME", "$PASSWORD", "''"]) > plantestsuite("samba.tests.pam_winbind(domain)", "ad_member", > [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), > valgrindify(python), pam_wrapper_so_path, >- "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD"]) >+ "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", "''"]) > > for pam_options in ["''", "use_authtok", "try_authtok"]: > plantestsuite("samba.tests.pam_winbind_chauthtok with options %s" % pam_options, "ad_member", >@@ -233,7 +233,7 @@ if with_pam: > plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain)", "ad_member", > [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), > valgrindify(python), pam_wrapper_so_path, >- "$DOMAIN", "alice", "Secret007"]) >+ "$DOMAIN", "alice", "Secret007", "''"]) > > > plantestsuite("samba.unittests.krb5samba", "none", >-- >2.17.1 > > >From cfee90317203e174c4553c264f47387afef7aeaa Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 01:25:23 +0200 >Subject: [PATCH 220/376] selftest/tests.py: prepare looping over pam_winbindd > tests > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 72daf99fd1ffd8269fce25d69458de35e2ae32cc) >--- > selftest/tests.py | 58 ++++++++++++++++++++++++++++++----------------- > 1 file changed, 37 insertions(+), 21 deletions(-) > >diff --git a/selftest/tests.py b/selftest/tests.py >index 2d3587837a3..95d027f9521 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -213,27 +213,43 @@ planpythontestsuite("none", "samba.tests.tdb_util") > planpythontestsuite("none", "samba.tests.samdb_api") > > if with_pam: >- plantestsuite("samba.tests.pam_winbind(local)", "ad_member", >- [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >- valgrindify(python), pam_wrapper_so_path, >- "$SERVER", "$USERNAME", "$PASSWORD", "''"]) >- plantestsuite("samba.tests.pam_winbind(domain)", "ad_member", >- [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >- valgrindify(python), pam_wrapper_so_path, >- "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", "''"]) >- >- for pam_options in ["''", "use_authtok", "try_authtok"]: >- plantestsuite("samba.tests.pam_winbind_chauthtok with options %s" % pam_options, "ad_member", >- [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_chauthtok.sh"), >- valgrindify(python), pam_wrapper_so_path, pam_set_items_so_path, >- "$DOMAIN", "TestPamOptionsUser", "oldp@ssword0", "newp@ssword0", >- pam_options, 'yes', >- "$DC_SERVER", "$DC_USERNAME", "$DC_PASSWORD"]) >- >- plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain)", "ad_member", >- [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), >- valgrindify(python), pam_wrapper_so_path, >- "$DOMAIN", "alice", "Secret007", "''"]) >+ env = "ad_member" >+ options = [ >+ { >+ "description": "default", >+ "pam_options": "", >+ }, >+ ] >+ for o in options: >+ description = o["description"] >+ pam_options = "'%s'" % o["pam_options"] >+ >+ plantestsuite("samba.tests.pam_winbind(local+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$SERVER", "$USERNAME", "$PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", >+ pam_options]) >+ >+ for authtok_options in ["", "use_authtok", "try_authtok"]: >+ _pam_options = "'%s %s'" % (o["pam_options"], authtok_options) >+ _description = "%s %s" % (description, authtok_options) >+ plantestsuite("samba.tests.pam_winbind_chauthtok(domain+%s)" % _description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_chauthtok.sh"), >+ valgrindify(python), pam_wrapper_so_path, pam_set_items_so_path, >+ "$DOMAIN", "TestPamOptionsUser", "oldp@ssword0", "newp@ssword0", >+ _pam_options, 'yes', >+ "$DC_SERVER", "$DC_USERNAME", "$DC_PASSWORD"]) >+ >+ plantestsuite("samba.tests.pam_winbind_warn_pwd_expire(domain+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind_warn_pwd_expire.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$DOMAIN", "alice", "Secret007", >+ pam_options]) > > > plantestsuite("samba.unittests.krb5samba", "none", >-- >2.17.1 > > >From e7b84754510b5850891752c5fc943714f0a46a4d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 08:08:57 +0200 >Subject: [PATCH 221/376] selftest/tests.py: test pam_winbind with krb5_auth > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 36e95e42ea8a7e5a4091a647215d06d2ab47fab6) >--- > selftest/tests.py | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/selftest/tests.py b/selftest/tests.py >index 95d027f9521..0bcb826071c 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -215,6 +215,10 @@ planpythontestsuite("none", "samba.tests.samdb_api") > if with_pam: > env = "ad_member" > options = [ >+ { >+ "description": "krb5", >+ "pam_options": "krb5_auth krb5_ccache_type=FILE", >+ }, > { > "description": "default", > "pam_options": "", >-- >2.17.1 > > >From 2290dfe49bf267784d3bec491cb9b8978c3d66dc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 14:03:34 +0200 >Subject: [PATCH 222/376] selftest/tests.py: test pam_winbind with a lot of > username variations > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit f07b542c61f84a97c097208e10bf9375ddfa9a15) >--- > selftest/tests.py | 27 ++++++++++++++++++++++++++- > 1 file changed, 26 insertions(+), 1 deletion(-) > >diff --git a/selftest/tests.py b/selftest/tests.py >index 0bcb826071c..e37cb9e7b96 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -233,11 +233,36 @@ if with_pam: > valgrindify(python), pam_wrapper_so_path, > "$SERVER", "$USERNAME", "$PASSWORD", > pam_options]) >- plantestsuite("samba.tests.pam_winbind(domain+%s)" % description, env, >+ plantestsuite("samba.tests.pam_winbind(domain1+%s)" % description, env, > [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), > valgrindify(python), pam_wrapper_so_path, > "$DOMAIN", "$DC_USERNAME", "$DC_PASSWORD", > pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain2+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$REALM", "$DC_USERNAME", "$DC_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain3+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", "${DC_USERNAME}@${DOMAIN}", "$DC_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain4+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", "${DC_USERNAME}@${REALM}", "$DC_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain5+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$REALM", "${DC_USERNAME}@${DOMAIN}", "$DC_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(domain6+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$DOMAIN", "${DC_USERNAME}@${REALM}", "$DC_PASSWORD", >+ pam_options]) > > for authtok_options in ["", "use_authtok", "try_authtok"]: > _pam_options = "'%s %s'" % (o["pam_options"], authtok_options) >-- >2.17.1 > > >From e3760d6e3a3d141719e47eed755805a330609cac Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 20 Mar 2017 11:39:41 +0100 >Subject: [PATCH 223/376] selftest: Export TRUST information in the ad_member > target environment > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit 13e3811c9510cf213881527877bed40092e0b33c) >--- > selftest/target/Samba.pm | 22 ++++++++++++++++++++++ > selftest/target/Samba3.pm | 24 ++++++++++++++++++++++-- > 2 files changed, 44 insertions(+), 2 deletions(-) > >diff --git a/selftest/target/Samba.pm b/selftest/target/Samba.pm >index ca3099c9d05..c30f6fe33ce 100644 >--- a/selftest/target/Samba.pm >+++ b/selftest/target/Samba.pm >@@ -724,6 +724,28 @@ my @exported_envvars = ( > "TRUST_REALM", > "TRUST_DOMSID", > >+ # stuff related to a trusted domain, on a trust_member >+ # the domain behind a forest trust (two-way) >+ "TRUST_F_BOTH_SERVER", >+ "TRUST_F_BOTH_SERVER_IP", >+ "TRUST_F_BOTH_SERVER_IPV6", >+ "TRUST_F_BOTH_NETBIOSNAME", >+ "TRUST_F_BOTH_USERNAME", >+ "TRUST_F_BOTH_PASSWORD", >+ "TRUST_F_BOTH_DOMAIN", >+ "TRUST_F_BOTH_REALM", >+ >+ # stuff related to a trusted domain, on a trust_member >+ # the domain behind an external trust (two-way) >+ "TRUST_E_BOTH_SERVER", >+ "TRUST_E_BOTH_SERVER_IP", >+ "TRUST_E_BOTH_SERVER_IPV6", >+ "TRUST_E_BOTH_NETBIOSNAME", >+ "TRUST_E_BOTH_USERNAME", >+ "TRUST_E_BOTH_PASSWORD", >+ "TRUST_E_BOTH_DOMAIN", >+ "TRUST_E_BOTH_REALM", >+ > # domain controller stuff > "DC_SERVER", > "DC_SERVER_IP", >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 131d576a767..52d78ea51c0 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -181,7 +181,7 @@ sub check_env($$) > > nt4_member => ["nt4_dc"], > >- ad_member => ["ad_dc"], >+ ad_member => ["ad_dc", "fl2008r2dc", "fl2003dc"], > ad_member_rfc2307 => ["ad_dc_ntvfs"], > ad_member_idmap_rid => ["ad_dc"], > ad_member_idmap_ad => ["fl2008r2dc"], >@@ -369,7 +369,7 @@ sub setup_nt4_member > > sub setup_ad_member > { >- my ($self, $prefix, $dcvars) = @_; >+ my ($self, $prefix, $dcvars, $trustvars_f, $trustvars_e) = @_; > > my $prefix_abs = abs_path($prefix); > my @dirs = (); >@@ -493,6 +493,26 @@ sub setup_ad_member > $ret->{DC_USERNAME} = $dcvars->{USERNAME}; > $ret->{DC_PASSWORD} = $dcvars->{PASSWORD}; > >+ # forest trust >+ $ret->{TRUST_F_BOTH_SERVER} = $trustvars_f->{SERVER}; >+ $ret->{TRUST_F_BOTH_SERVER_IP} = $trustvars_f->{SERVER_IP}; >+ $ret->{TRUST_F_BOTH_SERVER_IPV6} = $trustvars_f->{SERVER_IPV6}; >+ $ret->{TRUST_F_BOTH_NETBIOSNAME} = $trustvars_f->{NETBIOSNAME}; >+ $ret->{TRUST_F_BOTH_USERNAME} = $trustvars_f->{USERNAME}; >+ $ret->{TRUST_F_BOTH_PASSWORD} = $trustvars_f->{PASSWORD}; >+ $ret->{TRUST_F_BOTH_DOMAIN} = $trustvars_f->{DOMAIN}; >+ $ret->{TRUST_F_BOTH_REALM} = $trustvars_f->{REALM}; >+ >+ # external trust >+ $ret->{TRUST_E_BOTH_SERVER} = $trustvars_e->{SERVER}; >+ $ret->{TRUST_E_BOTH_SERVER_IP} = $trustvars_e->{SERVER_IP}; >+ $ret->{TRUST_E_BOTH_SERVER_IPV6} = $trustvars_e->{SERVER_IPV6}; >+ $ret->{TRUST_E_BOTH_NETBIOSNAME} = $trustvars_e->{NETBIOSNAME}; >+ $ret->{TRUST_E_BOTH_USERNAME} = $trustvars_e->{USERNAME}; >+ $ret->{TRUST_E_BOTH_PASSWORD} = $trustvars_e->{PASSWORD}; >+ $ret->{TRUST_E_BOTH_DOMAIN} = $trustvars_e->{DOMAIN}; >+ $ret->{TRUST_E_BOTH_REALM} = $trustvars_e->{REALM}; >+ > return $ret; > } > >-- >2.17.1 > > >From f0f2ce68e450dbf9f8f7e2257dee9e5e00c29567 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 10 Jun 2017 14:38:40 +0200 >Subject: [PATCH 224/376] selftest/tests.py: test pam_winbind for trusts > domains > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit ad6f0e056ac27ab5c078dbdbff44372da05caab2) >--- > selftest/tests.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 84 insertions(+) > >diff --git a/selftest/tests.py b/selftest/tests.py >index e37cb9e7b96..e767f276353 100644 >--- a/selftest/tests.py >+++ b/selftest/tests.py >@@ -263,6 +263,90 @@ if with_pam: > valgrindify(python), pam_wrapper_so_path, > "$DOMAIN", "${DC_USERNAME}@${REALM}", "$DC_PASSWORD", > pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both1+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$TRUST_F_BOTH_DOMAIN", >+ "$TRUST_F_BOTH_USERNAME", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both2+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$TRUST_F_BOTH_REALM", >+ "$TRUST_F_BOTH_USERNAME", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both3+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", >+ "${TRUST_F_BOTH_USERNAME}@${TRUST_F_BOTH_DOMAIN}", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both4+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", >+ "${TRUST_F_BOTH_USERNAME}@${TRUST_F_BOTH_REALM}", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both5+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "${TRUST_F_BOTH_REALM}", >+ "${TRUST_F_BOTH_USERNAME}@${TRUST_F_BOTH_DOMAIN}", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_f_both6+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "${TRUST_F_BOTH_DOMAIN}", >+ "${TRUST_F_BOTH_USERNAME}@${TRUST_F_BOTH_REALM}", >+ "$TRUST_F_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both1+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$TRUST_E_BOTH_DOMAIN", >+ "$TRUST_E_BOTH_USERNAME", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both2+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "$TRUST_E_BOTH_REALM", >+ "$TRUST_E_BOTH_USERNAME", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both3+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", >+ "${TRUST_E_BOTH_USERNAME}@${TRUST_E_BOTH_DOMAIN}", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both4+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "''", >+ "${TRUST_E_BOTH_USERNAME}@${TRUST_E_BOTH_REALM}", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both5+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "${TRUST_E_BOTH_REALM}", >+ "${TRUST_E_BOTH_USERNAME}@${TRUST_E_BOTH_DOMAIN}", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) >+ plantestsuite("samba.tests.pam_winbind(trust_e_both6+%s)" % description, env, >+ [os.path.join(srcdir(), "python/samba/tests/test_pam_winbind.sh"), >+ valgrindify(python), pam_wrapper_so_path, >+ "${TRUST_E_BOTH_DOMAIN}", >+ "${TRUST_E_BOTH_USERNAME}@${TRUST_E_BOTH_REALM}", >+ "$TRUST_E_BOTH_PASSWORD", >+ pam_options]) > > for authtok_options in ["", "use_authtok", "try_authtok"]: > _pam_options = "'%s %s'" % (o["pam_options"], authtok_options) >-- >2.17.1 > > >From f836385629c097ec8564ac19045c5906fdb13f64 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 08:02:38 +0200 >Subject: [PATCH 225/376] selftest/Samba3.pm: use "winbind scan trusted domains > = no" for ad_member > >This demonstrates that we rely on knowning about trusted domains before >we can do krb5_auth in winbindd. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> >(cherry picked from commit e2737a74d4453a3d65e5466ddc4405d68444df27) >--- > selftest/knownfail.d/pam_winbind_krb5 | 1 + > selftest/target/Samba3.pm | 1 + > 2 files changed, 2 insertions(+) > create mode 100644 selftest/knownfail.d/pam_winbind_krb5 > >diff --git a/selftest/knownfail.d/pam_winbind_krb5 b/selftest/knownfail.d/pam_winbind_krb5 >new file mode 100644 >index 00000000000..1dd0c7d3f1c >--- /dev/null >+++ b/selftest/knownfail.d/pam_winbind_krb5 >@@ -0,0 +1 @@ >+^samba.tests.pam_winbind.trust_._both..krb5..samba.tests.pam_winbind.SimplePamTests.test_authenticate >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index 52d78ea51c0..a75ec094b5e 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -416,6 +416,7 @@ sub setup_ad_member > template homedir = /home/%D/%G/%U > auth event notification = true > password server = $dcvars->{SERVER} >+ winbind scan trusted domains = no > > [sub_dug] > path = $share_dir/D_%D/U_%U/G_%G >-- >2.17.1 > > >From fcb247f41478e8b1f8ff504e901cefc047bdf197 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 18 Sep 2019 08:10:26 +0200 >Subject: [PATCH 226/376] selftest/Samba3.pm: use "winbind use krb5 enterprise > principals = yes" for ad_member >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This demonstrates that can do krb5_auth in winbindd without knowning about trusted domains. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14124 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Guenther Deschner <gd@samba.org> > >Autobuild-User(master): Günther Deschner <gd@samba.org> >Autobuild-Date(master): Tue Sep 24 19:51:29 UTC 2019 on sn-devel-184 > >(cherry picked from commit 0ee085b594878f5e0e83839f465303754f015459) >--- > selftest/knownfail.d/pam_winbind_krb5 | 1 - > selftest/target/Samba3.pm | 1 + > 2 files changed, 1 insertion(+), 1 deletion(-) > delete mode 100644 selftest/knownfail.d/pam_winbind_krb5 > >diff --git a/selftest/knownfail.d/pam_winbind_krb5 b/selftest/knownfail.d/pam_winbind_krb5 >deleted file mode 100644 >index 1dd0c7d3f1c..00000000000 >--- a/selftest/knownfail.d/pam_winbind_krb5 >+++ /dev/null >@@ -1 +0,0 @@ >-^samba.tests.pam_winbind.trust_._both..krb5..samba.tests.pam_winbind.SimplePamTests.test_authenticate >diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm >index a75ec094b5e..32bd8698df2 100755 >--- a/selftest/target/Samba3.pm >+++ b/selftest/target/Samba3.pm >@@ -417,6 +417,7 @@ sub setup_ad_member > auth event notification = true > password server = $dcvars->{SERVER} > winbind scan trusted domains = no >+ winbind use krb5 enterprise principals = yes > > [sub_dug] > path = $share_dir/D_%D/U_%U/G_%G >-- >2.17.1 > > >From 75702977dde834f06460e8434ea98b81020efbe2 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Mon, 23 Sep 2019 08:57:33 +0200 >Subject: [PATCH 227/376] fault.c: improve fault_report message text pointing > to our wiki > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14139 > >Signed-off-by: Bjoern Jacke <bjacke@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit ec4c5975528f3d3ab9c8813e176c6d1a2f1ca506) >--- > lib/util/fault.c | 6 +++++- > 1 file changed, 5 insertions(+), 1 deletion(-) > >diff --git a/lib/util/fault.c b/lib/util/fault.c >index 5be9162679e..c42bc51789a 100644 >--- a/lib/util/fault.c >+++ b/lib/util/fault.c >@@ -78,7 +78,11 @@ static void fault_report(int sig) > > DEBUGSEP(0); > DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),SAMBA_VERSION_STRING)); >- DEBUG(0,("\nPlease read the Trouble-Shooting section of the Samba HOWTO\n")); >+ DEBUG(0,("\nIf you are running a recent Samba version, and " >+ "if you think this problem is not yet fixed in the " >+ "latest versions, please consider reporting this " >+ "bug, see " >+ "https://wiki.samba.org/index.php/Bug_Reporting\n")); > DEBUGSEP(0); > > smb_panic("internal error"); >-- >2.17.1 > > >From a89e8588449a09f47250e81d87828de74d4c5106 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Thu, 12 Sep 2019 16:39:10 +0200 >Subject: [PATCH 228/376] s3-winbindd: fix forest trusts with additional trust > attributes. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14130 > >Guenther > >Signed-off-by: Guenther Deschner <gd@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit d78c87e665e23e6470a19a69383ede7137172c26) >--- > source3/winbindd/winbindd_ads.c | 2 +- > source3/winbindd/winbindd_util.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c >index 5f20cfb7f76..485ca831be9 100644 >--- a/source3/winbindd/winbindd_ads.c >+++ b/source3/winbindd/winbindd_ads.c >@@ -1457,7 +1457,7 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain, > */ > > if ((trust->trust_attributes >- == LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && >+ & LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) && > !domain->primary ) > { > DEBUG(10,("trusted_domains: Skipping external trusted " >diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c >index cc4c3f7391a..ee7651c9639 100644 >--- a/source3/winbindd/winbindd_util.c >+++ b/source3/winbindd/winbindd_util.c >@@ -723,7 +723,7 @@ static void rescan_forest_trusts( void ) > > if ( (flags & NETR_TRUST_FLAG_INBOUND) && > (type == LSA_TRUST_TYPE_UPLEVEL) && >- (attribs == LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) >+ (attribs & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) > { > /* add the trusted domain if we don't know > about it */ >-- >2.17.1 > > >From 4709a848c550e6b56a8a94ca722fa6ab091e3725 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 15:18:55 +0200 >Subject: [PATCH 229/376] s3:waf: Do not check for nanosleep() as we don't use > it anywhere >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >We use usleep() in the meantime. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 952e1812fa9bdc1bac2a7ae5ebb5532f1ea31447) >--- > source3/wscript | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/source3/wscript b/source3/wscript >index 4a3e75605e7..7b257bcb845 100644 >--- a/source3/wscript >+++ b/source3/wscript >@@ -116,7 +116,6 @@ def configure(conf): > conf.CHECK_FUNCS('fstatat') > conf.CHECK_FUNCS('getpwent_r setenv clearenv strcasecmp fcvt fcvtl') > conf.CHECK_FUNCS('syslog vsyslog timegm setlocale') >- conf.CHECK_FUNCS_IN('nanosleep', 'rt') > conf.CHECK_FUNCS('lutimes futimes utimensat futimens') > conf.CHECK_FUNCS('mlock munlock mlockall munlockall') > conf.CHECK_FUNCS('memalign posix_memalign hstrerror') >-- >2.17.1 > > >From 7ec980b991fd5b62e5739a5fdb2dcbb1306c52d9 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 15:14:24 +0200 >Subject: [PATCH 230/376] replace: Only link against librt if really needed >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >fdatasync() and clock_gettime() are provided by glibc on Linux, so there >is no need to link against librt. Checks have been added so if there are >platforms which require it are still functional. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 480152dd6729d4c58faca6f3e4fa91ff4614c272) >--- > lib/replace/wscript | 24 +++++++++++++++++++++--- > 1 file changed, 21 insertions(+), 3 deletions(-) > >diff --git a/lib/replace/wscript b/lib/replace/wscript >index 4df1b4d77c4..ec5e085a350 100644 >--- a/lib/replace/wscript >+++ b/lib/replace/wscript >@@ -458,11 +458,28 @@ def configure(conf): > conf.CHECK_C_PROTOTYPE('dlopen', 'void *dlopen(const char* filename, unsigned int flags)', > define='DLOPEN_TAKES_UNSIGNED_FLAGS', headers='dlfcn.h dl.h') > >- if conf.CHECK_FUNCS_IN('fdatasync', 'rt', checklibc=True): >+ # >+ # Check for clock_gettime and fdatasync >+ # >+ # First check libc to avoid linking libreplace against librt. >+ # >+ if conf.CHECK_FUNCS('fdatasync'): > # some systems are missing the declaration > conf.CHECK_DECLS('fdatasync') >+ else: >+ if conf.CHECK_FUNCS_IN('fdatasync', 'rt'): >+ # some systems are missing the declaration >+ conf.CHECK_DECLS('fdatasync') >+ >+ has_clock_gettime = False >+ if conf.CHECK_FUNCS('clock_gettime'): >+ has_clock_gettime = True >+ >+ if not has_clock_gettime: >+ if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): >+ has_clock_gettime = True > >- if conf.CHECK_FUNCS_IN('clock_gettime', 'rt', checklibc=True): >+ if has_clock_gettime: > for c in ['CLOCK_MONOTONIC', 'CLOCK_PROCESS_CPUTIME_ID', 'CLOCK_REALTIME']: > conf.CHECK_CODE(''' > #if TIME_WITH_SYS_TIME >@@ -816,6 +833,7 @@ def build(bld): > > extra_libs = '' > if bld.CONFIG_SET('HAVE_LIBBSD'): extra_libs += ' bsd' >+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' > > bld.SAMBA_SUBSYSTEM('LIBREPLACE_HOSTCC', > REPLACE_HOSTCC_SOURCE, >@@ -856,7 +874,7 @@ def build(bld): > # at the moment: > # hide_symbols=bld.BUILTIN_LIBRARY('replace'), > private_library=True, >- deps='crypt dl nsl socket rt attr' + extra_libs) >+ deps='crypt dl nsl socket attr' + extra_libs) > > replace_test_cflags = '' > if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'): >-- >2.17.1 > > >From 82c9a6c4b0adfc472b342c898c2cb3b382132c53 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 16:10:35 +0200 >Subject: [PATCH 231/376] pthreadpool: Only link pthreadpool against librt if > we have to >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This calls clock_gettime() which is available in glibc on Linux. If the >wscript in libreplace detected that librt is needed for clock_gettime() >we have to link against it. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 4b28239d13b17e42eb5aa4b405342f46347f3de4) >--- > lib/pthreadpool/wscript_build | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/lib/pthreadpool/wscript_build b/lib/pthreadpool/wscript_build >index 57df25548b1..70aa7cbf041 100644 >--- a/lib/pthreadpool/wscript_build >+++ b/lib/pthreadpool/wscript_build >@@ -1,12 +1,17 @@ > #!/usr/bin/env python > > if bld.env.WITH_PTHREADPOOL: >+ extra_libs='' >+ >+ # Link to librt if needed for clock_gettime() >+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' >+ > bld.SAMBA_SUBSYSTEM('PTHREADPOOL', > source='''pthreadpool.c > pthreadpool_pipe.c > pthreadpool_tevent.c > ''', >- deps='pthread rt replace tevent-util') >+ deps='pthread replace tevent-util' + extra_libs) > else: > bld.SAMBA_SUBSYSTEM('PTHREADPOOL', > source='''pthreadpool_sync.c >-- >2.17.1 > > >From 62f0ce14a1b8e03e4c4fd8710df86a9a58bca73b Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 17:04:57 +0200 >Subject: [PATCH 232/376] third_party: Only link cmocka against librt if really > needed >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >cmocka also uses clock_gettime(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 36e8d715bc8dc1e8466f5a5c9798df76310b7572) >--- > third_party/cmocka/wscript | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > >diff --git a/third_party/cmocka/wscript b/third_party/cmocka/wscript >index 9ebdd7cfbe9..3c2ad50801a 100644 >--- a/third_party/cmocka/wscript >+++ b/third_party/cmocka/wscript >@@ -12,8 +12,13 @@ def build(bld): > if bld.CONFIG_SET('USING_SYSTEM_CMOCKA'): > return > >+ extra_libs='' >+ >+ # Link to librt if needed for clock_gettime() >+ if bld.CONFIG_SET('HAVE_LIBRT'): extra_libs += ' rt' >+ > bld.SAMBA_LIBRARY('cmocka', > source='cmocka.c', >- deps='rt', >+ deps=extra_libs, > allow_warnings=True, > private_library=True) >-- >2.17.1 > > >From 48cd645d1d81fae6f528e3cc7e83b3d9ad1caefd Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 17:39:29 +0200 >Subject: [PATCH 233/376] third_party: Link nss_wrapper against pthread >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >nss_wrapper uses pthread_atfork() which is only provided by libpthread. >So we need an explicit dependency. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 68d8a02ef57cce29e4ff3ef1b792adfc10d0b916) >--- > third_party/nss_wrapper/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/third_party/nss_wrapper/wscript b/third_party/nss_wrapper/wscript >index 127b5207c5e..7a2f53ad299 100644 >--- a/third_party/nss_wrapper/wscript >+++ b/third_party/nss_wrapper/wscript >@@ -90,6 +90,6 @@ def build(bld): > # breaks preloading! > bld.SAMBA_LIBRARY('nss_wrapper', > source='nss_wrapper.c', >- deps='dl', >+ deps='dl pthread', > install=False, > realname='libnss-wrapper.so') >-- >2.17.1 > > >From b5dfe882ecbe5317c12971d83140b59a0d24da6b Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 17:40:13 +0200 >Subject: [PATCH 234/376] third_party: Link uid_wrapper against pthread >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >uid_wrapper uses pthread_atfork() which is only provided by libpthread. â···················· >So we need an explicit dependency. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit bd0cd8e13234d684da77a65f6fdaea2572625369) >--- > third_party/uid_wrapper/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/third_party/uid_wrapper/wscript b/third_party/uid_wrapper/wscript >index 61d8a189625..738343f49e4 100644 >--- a/third_party/uid_wrapper/wscript >+++ b/third_party/uid_wrapper/wscript >@@ -119,6 +119,6 @@ def build(bld): > # breaks preloading! > bld.SAMBA_LIBRARY('uid_wrapper', > source='uid_wrapper.c', >- deps='dl', >+ deps='dl pthread', > install=False, > realname='libuid-wrapper.so') >-- >2.17.1 > > >From 0182ccfd22bfd002d9c1d1f04372fccd642cfc0e Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Mon, 23 Sep 2019 16:53:12 +0200 >Subject: [PATCH 235/376] waf:replace: Do not link against libpthread if not > necessary >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >On Linux we should avoid linking everything against libpthread. Symbols >used my most application are provided by glibc and code which deals with >threads has to explicitly link against libpthread. This avoids setting >LDFLAGS=-pthread globally. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14140 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Signed-off-by: Isaac Boukris <iboukris@gmail.com> >Pair-Programmed-With: Isaac Boukris <iboukris@gmail.com> >Reviewed-by: Matthias Dieter Wallnöfer <mdw@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 9499db075b72b147e2ff9bb78e9d5edbaac14e69) >--- > lib/replace/wscript | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > >diff --git a/lib/replace/wscript b/lib/replace/wscript >index ec5e085a350..240d730cbee 100644 >--- a/lib/replace/wscript >+++ b/lib/replace/wscript >@@ -552,6 +552,11 @@ def configure(conf): > PTHREAD_CFLAGS='error' > PTHREAD_LDFLAGS='error' > >+ if PTHREAD_LDFLAGS == 'error': >+ # Check if pthread_attr_init() is provided by libc first! >+ if conf.CHECK_FUNCS('pthread_attr_init'): >+ PTHREAD_CFLAGS='-D_REENTRANT' >+ PTHREAD_LDFLAGS='' > if PTHREAD_LDFLAGS == 'error': > if conf.CHECK_FUNCS_IN('pthread_attr_init', 'pthread'): > PTHREAD_CFLAGS='-D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS' >@@ -564,10 +569,7 @@ def configure(conf): > if conf.CHECK_FUNCS_IN('pthread_attr_init', 'c_r'): > PTHREAD_CFLAGS='-D_THREAD_SAFE -pthread' > PTHREAD_LDFLAGS='-pthread' >- if PTHREAD_LDFLAGS == 'error': >- if conf.CHECK_FUNCS('pthread_attr_init'): >- PTHREAD_CFLAGS='-D_REENTRANT' >- PTHREAD_LDFLAGS='-lpthread' >+ > # especially for HP-UX, where the CHECK_FUNC macro fails to test for > # pthread_attr_init. On pthread_mutex_lock it works there... > if PTHREAD_LDFLAGS == 'error': >-- >2.17.1 > > >From 4a43d8b996b1ce444596ed41a686be5ae526113d Mon Sep 17 00:00:00 2001 >From: Christof Schmitt <cs@samba.org> >Date: Wed, 25 Sep 2019 17:19:27 -0700 >Subject: [PATCH 236/376] selftest: Test ID_TYPE_BOTH with idmap_rid module > >ID_TYPE_BOTH means that each user and group has two mappings, a uid and >gid. In addition the calls to getpwent, getpwuid, getgrent and getgrgid >always return some information, so that uid and gid can be mapped to a >name. Establish a test to verify that the expected information is >returned. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14141 > >Signed-off-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit 485874d6bb328c50c9a98785e85270f28ade7497) >--- > nsswitch/tests/test_idmap_rid.sh | 132 +++++++++++++++++++++++ > selftest/knownfail.d/passwd-id-type-both | 4 + > 2 files changed, 136 insertions(+) > create mode 100644 selftest/knownfail.d/passwd-id-type-both > >diff --git a/nsswitch/tests/test_idmap_rid.sh b/nsswitch/tests/test_idmap_rid.sh >index 8209a50a4fc..4e6477f666e 100755 >--- a/nsswitch/tests/test_idmap_rid.sh >+++ b/nsswitch/tests/test_idmap_rid.sh >@@ -63,4 +63,136 @@ test "$out" = "$SID -> unmapped" > ret=$? > testit "Bogus SID returns unmapped" test $ret -eq 0 || failed=$(expr $failed + 1) > >+# >+# Test 3: ID_TYPE_BOTH mappings for group >+# >+ >+GROUP="$DOMAIN/Domain Users" >+GROUP_SID=$($wbinfo --name-to-sid="$GROUP" | sed -e 's/ .*//') >+ >+uid=$($wbinfo --sid-to-uid=$GROUP_SID) >+ret=$? >+testit "ID_TYPE_BOTH group map to uid succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+testit "ID_TYPE_BOTH group map to uid has result" test -n $uid ||\ >+ failed=$(expr $failed + 1) >+ >+gid=$($wbinfo --sid-to-gid=$GROUP_SID) >+ret=$? >+testit "ID_TYPE_BOTH group map to gid succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+testit "ID_TYPE_BOTH group map to gid has result" test -n $gid ||\ >+ failed=$(expr $failed + 1) >+ >+testit "ID_TYPE_BOTH group uid equals gid" test $uid -eq $gid ||\ >+ failed=$(expr $failed + 1) >+ >+group_pw="$DOMAIN/domain users:*:$uid:$gid::/home/$DOMAIN/domain users:/bin/false" >+ >+out=$(getent passwd "$GROUP") >+ret=$? >+testit "getpwnam for ID_TYPE_BOTH group succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+test "$out" = "$group_pw" >+ret=$? >+testit "getpwnam for ID_TYPE_BOTH group output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+out=$(getent passwd $uid) >+ret=$? >+testit "getpwuid for ID_TYPE_BOTH group succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$group_pw" >+ret=$? >+testit "getpwuid for ID_TYPE_BOTH group output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+group_gr="$DOMAIN/domain users:x:$gid:" >+ >+out=$(getent group "$GROUP") >+ret=$? >+testit "getgrnam for ID_TYPE_BOTH group succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$group_gr" >+ret=$? >+testit "getgrnam for ID_TYPE_BOTH group output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+out=$(getent group "$gid") >+ret=$? >+testit "getgrgid for ID_TYPE_BOTH group succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$group_gr" >+ret=$? >+testit "getgrgid for ID_TYPE_BOTH group output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+# >+# Test 4: ID_TYPE_BOTH mappings for user >+# >+ >+dom_users_gid=$gid >+ >+USER="$DOMAIN/Administrator" >+USER_SID=$($wbinfo --name-to-sid="$USER" | sed -e 's/ .*//') >+ >+uid=$($wbinfo --sid-to-uid=$USER_SID) >+ret=$? >+testit "ID_TYPE_BOTH user map to uid succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+testit "ID_TYPE_BOTH user map to uid has result" test -n $uid ||\ >+ failed=$(expr $failed + 1) >+ >+gid=$($wbinfo --sid-to-gid=$USER_SID) >+ret=$? >+testit "ID_TYPE_BOTH user map to gid succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+testit "ID_TYPE_BOTH user map to gid has result" test -n $gid ||\ >+ failed=$(expr $failed + 1) >+ >+testit "ID_TYPE_BOTH user uid equals gid" test $uid -eq $gid ||\ >+ failed=$(expr $failed + 1) >+ >+user_pw="$DOMAIN/administrator:*:$uid:$dom_users_gid::/home/$DOMAIN/administrator:/bin/false" >+ >+out=$(getent passwd "$USER") >+ret=$? >+testit "getpwnam for ID_TYPE_BOTH user succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+test "$out" = "$user_pw" >+ret=$? >+testit "getpwnam for ID_TYPE_BOTH user output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+out=$(getent passwd $uid) >+ret=$? >+testit "getpwuid for ID_TYPE_BOTH user succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$user_pw" >+ret=$? >+testit "getpwuid for ID_TYPE_BOTH user output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+user_gr="$DOMAIN/administrator:x:$gid:$DOMAIN/administrator" >+ >+out=$(getent group "$USER") >+ret=$? >+testit "getgrnam for ID_TYPE_BOTH user succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$user_gr" >+ret=$? >+testit "getgrnam for ID_TYPE_BOTH user output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ >+out=$(getent group "$gid") >+ret=$? >+testit "getgrgid for ID_TYPE_BOTH user succeeds" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+test "$out" = "$user_gr" >+ret=$? >+testit "getgrgid for ID_TYPE_BOTH user output" test $ret -eq 0 ||\ >+ failed=$(expr $failed + 1) >+ > exit $failed >diff --git a/selftest/knownfail.d/passwd-id-type-both b/selftest/knownfail.d/passwd-id-type-both >new file mode 100644 >index 00000000000..e969ef8d165 >--- /dev/null >+++ b/selftest/knownfail.d/passwd-id-type-both >@@ -0,0 +1,4 @@ >+idmap\.rid.getpwnam for ID_TYPE_BOTH group succeeds\(ad_member_idmap_rid\) >+idmap\.rid.getpwnam for ID_TYPE_BOTH group output\(ad_member_idmap_rid\) >+idmap\.rid.getpwuid for ID_TYPE_BOTH group succeeds\(ad_member_idmap_rid\) >+idmap\.rid.getpwuid for ID_TYPE_BOTH group output\(ad_member_idmap_rid\) >-- >2.17.1 > > >From 42d530b0dbc1b1389b393c648357de31e4c11e9f Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Fri, 11 Jan 2019 10:44:30 +0100 >Subject: [PATCH 237/376] winbind: provide passwd struct for group sid with > ID_TYPE_BOTH mapping (again) > >https://git.samba.org/?p=samba.git;a=commitdiff;h=394622ef8c916cf361f8596dba4664dc8d6bfc9e >originally introduced the above feature. > >This functionality was undone as part of "winbind: Restructure get_pwsid" >https://git.samba.org/?p=samba.git;a=commitdiff;h=bce19a6efe11980933531f0349c8f5212419366a >I think that this semantic change was accidential. > >This patch undoes the semantic change and re-establishes the >functionality. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14141 > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Christof Schmitt <cs@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Christof Schmitt <cs@samba.org> >Autobuild-Date(master): Fri Sep 27 17:25:29 UTC 2019 on sn-devel-184 > >(cherry picked from commit 63c9147f8631d73b52bdd36ff407e0361dcf5178) > >Autobuild-User(v4-11-test): Karolin Seeger <kseeger@samba.org> >Autobuild-Date(v4-11-test): Wed Oct 2 11:06:20 UTC 2019 on sn-devel-184 >--- > selftest/knownfail.d/passwd-id-type-both | 4 ---- > source3/winbindd/wb_queryuser.c | 18 ++++++++++++++++-- > 2 files changed, 16 insertions(+), 6 deletions(-) > delete mode 100644 selftest/knownfail.d/passwd-id-type-both > >diff --git a/selftest/knownfail.d/passwd-id-type-both b/selftest/knownfail.d/passwd-id-type-both >deleted file mode 100644 >index e969ef8d165..00000000000 >--- a/selftest/knownfail.d/passwd-id-type-both >+++ /dev/null >@@ -1,4 +0,0 @@ >-idmap\.rid.getpwnam for ID_TYPE_BOTH group succeeds\(ad_member_idmap_rid\) >-idmap\.rid.getpwnam for ID_TYPE_BOTH group output\(ad_member_idmap_rid\) >-idmap\.rid.getpwuid for ID_TYPE_BOTH group succeeds\(ad_member_idmap_rid\) >-idmap\.rid.getpwuid for ID_TYPE_BOTH group output\(ad_member_idmap_rid\) >diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c >index 17170c3352a..2eb61406fc5 100644 >--- a/source3/winbindd/wb_queryuser.c >+++ b/source3/winbindd/wb_queryuser.c >@@ -166,8 +166,22 @@ static void wb_queryuser_got_domain(struct tevent_req *subreq) > return; > } > >- if (type != SID_NAME_USER) { >- /* allow SID_NAME_COMPUTER? */ >+ switch (type) { >+ case SID_NAME_USER: >+ case SID_NAME_COMPUTER: >+ /* >+ * user case: we only need the account name from lookup_sids >+ */ >+ break; >+ case SID_NAME_DOM_GRP: >+ case SID_NAME_ALIAS: >+ case SID_NAME_WKN_GRP: >+ /* >+ * also treat group-type SIDs (they might map to ID_TYPE_BOTH) >+ */ >+ sid_copy(&info->group_sid, &info->user_sid); >+ break; >+ default: > tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); > return; > } >-- >2.17.1 > > >From e8cba5a8a88b47274305b56132a399117d074476 Mon Sep 17 00:00:00 2001 >From: Amitay Isaacs <amitay@gmail.com> >Date: Mon, 30 Sep 2019 16:34:35 +1000 >Subject: [PATCH 238/376] ctdb-vacuum: Process all records not deleted on a > remote node > >This currently skips the last record. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14147 >RN: Avoid potential data loss during recovery after vacuuming error > >Signed-off-by: Amitay Isaacs <amitay@gmail.com> >Reviewed-by: Martin Schwenke <martin@meltin.net> >(cherry picked from commit 33f1c9d9654fbdcb99c23f9d23c4bbe2cc596b98) >--- > ctdb/server/ctdb_vacuum.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/ctdb/server/ctdb_vacuum.c b/ctdb/server/ctdb_vacuum.c >index 0c3770267bc..4fd11e3738c 100644 >--- a/ctdb/server/ctdb_vacuum.c >+++ b/ctdb/server/ctdb_vacuum.c >@@ -814,7 +814,7 @@ static void ctdb_process_delete_list(struct ctdb_db_context *ctdb_db, > */ > records = (struct ctdb_marshall_buffer *)outdata.dptr; > rec = (struct ctdb_rec_data_old *)&records->data[0]; >- while (records->count-- > 1) { >+ while (records->count-- > 0) { > TDB_DATA reckey, recdata; > struct ctdb_ltdb_header *rechdr; > struct delete_record_data *dd; >-- >2.17.1 > > >From 2ce14ef46a5d5d9ab6b9c30f1fb00debc1be71a4 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 3 Oct 2019 14:02:13 -0700 >Subject: [PATCH 239/376] s3: smbclient: Stop an SMB2-connection from > blundering into SMB1-specific calls. > >Fix in the same way this was done in SMBC_opendir_ctx() for libsmbclient. >This fix means the admin no longer has to remember to set 'min client protocol =' >when connecting to an SMB2-only server (MacOSX for example) and trying to >list shares. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=14152 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit ea82bca8cef0d736305a7a40b3198fc55ea66af8) >--- > source3/client/client.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source3/client/client.c b/source3/client/client.c >index 7a7ecd92eb6..e1de711c8e4 100644 >--- a/source3/client/client.c >+++ b/source3/client/client.c >@@ -4918,6 +4918,10 @@ static bool browse_host(bool sort) > return false; > } > >+ if (smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1) { >+ return false; >+ } >+ > ret = cli_RNetShareEnum(cli, browse_fn, NULL); > if (ret == -1) { > NTSTATUS status = cli_nt_error(cli); >-- >2.17.1 > > >From adfcddc681564ff278cbbf243f1a245ec62f0dbe Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Thu, 8 Aug 2019 14:35:38 +0200 >Subject: [PATCH 240/376] testprogs: Fix failure count in test_net_ads.sh > >There are missing ` at the end of the line. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13884 > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 320b5be4dce95d8dac4b3c0847faf5b730754a37) >--- > testprogs/blackbox/test_net_ads.sh | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh >index d3c4de5b741..512aa9d2952 100755 >--- a/testprogs/blackbox/test_net_ads.sh >+++ b/testprogs/blackbox/test_net_ads.sh >@@ -141,10 +141,10 @@ testit "test spn service doensn't exist in AD but is present in keytab file afte > # SPN parser is very basic but does detect some illegal combination > > windows_spn="$spn_service/$spn_host:" >-testit_expect_failure "test (dedicated keytab) fail to parse windows spn with missing port" $VALGRIND $net_tool ads keytab add $windows_spn -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1 >+testit_expect_failure "test (dedicated keytab) fail to parse windows spn with missing port" $VALGRIND $net_tool ads keytab add $windows_spn -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1` > > windows_spn="$spn_service/$spn_host/" >-testit_expect_failure "test (dedicated keytab) fail to parse windows spn with missing servicename" $VALGRIND $net_tool ads keytab add $windows_spn -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1 >+testit_expect_failure "test (dedicated keytab) fail to parse windows spn with missing servicename" $VALGRIND $net_tool ads keytab add $windows_spn -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1` > > testit "changetrustpw (dedicated keytab)" $VALGRIND $net_tool ads changetrustpw || failed=`expr $failed + 1` > >-- >2.17.1 > > >From 90566a8ef442fefbd9b8b10789eaebd6349ef266 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 13 Aug 2019 17:06:58 +0200 >Subject: [PATCH 241/376] s3:libads: Use ldap_add_ext_s() in ads_gen_add() > >ldap_add_s() is marked as deprecated. > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 456322a61319a10aaedda5244488ea4e5aa5cb64) >--- > source3/libads/ldap.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index 2110390b65f..66aea348e23 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -1596,7 +1596,7 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_dn, ADS_MODLIST mods) > /* make sure the end of the list is NULL */ > mods[i] = NULL; > >- ret = ldap_add_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods); >+ ret = ldap_add_ext_s(ads->ldap.ld, utf8_dn, (LDAPMod**)mods, NULL, NULL); > ads_print_error(ret, ads->ldap.ld); > TALLOC_FREE(utf8_dn); > return ADS_ERROR(ret); >-- >2.17.1 > > >From 2fa6dc27f37652a4ccc9cd0e5e159e69364b7064 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 13 Aug 2019 17:41:40 +0200 >Subject: [PATCH 242/376] s3:libnet: Require sealed LDAP SASL connections for > joining > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit b84abb3a46211dc84e52ef95750627e4dd081f2f) >--- > libgpo/pygpo.c | 2 +- > source3/lib/netapi/joindomain.c | 5 ++++- > source3/libads/ads_proto.h | 9 ++++++++- > source3/libads/ads_struct.c | 14 +++++++++++++- > source3/libads/ldap.c | 4 ++-- > source3/libnet/libnet_join.c | 3 ++- > source3/libsmb/namequery_dc.c | 2 +- > source3/printing/nt_printing_ads.c | 6 +++--- > source3/utils/net_ads.c | 13 +++++++++---- > source3/winbindd/winbindd_ads.c | 5 ++++- > source3/winbindd/winbindd_cm.c | 5 ++++- > 11 files changed, 51 insertions(+), 17 deletions(-) > >diff --git a/libgpo/pygpo.c b/libgpo/pygpo.c >index b1f788d3a00..581d20e0649 100644 >--- a/libgpo/pygpo.c >+++ b/libgpo/pygpo.c >@@ -210,7 +210,7 @@ static int py_ads_init(ADS *self, PyObject *args, PyObject *kwds) > self->ads_ptr = NULL; > } > /* always succeeds or crashes */ >- self->ads_ptr = ads_init(realm, workgroup, ldap_server); >+ self->ads_ptr = ads_init(realm, workgroup, ldap_server, ADS_SASL_PLAIN); > > return 0; > } >diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c >index ff2154ba803..8d0752f4531 100644 >--- a/source3/lib/netapi/joindomain.c >+++ b/source3/lib/netapi/joindomain.c >@@ -411,7 +411,10 @@ WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx, > > dc = strip_hostname(info->dc_unc); > >- ads = ads_init(info->domain_name, info->domain_name, dc); >+ ads = ads_init(info->domain_name, >+ info->domain_name, >+ dc, >+ ADS_SASL_PLAIN); > if (!ads) { > return WERR_GEN_FAILURE; > } >diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h >index 154bf67f964..92bb3a22cdb 100644 >--- a/source3/libads/ads_proto.h >+++ b/source3/libads/ads_proto.h >@@ -32,6 +32,12 @@ > #ifndef _LIBADS_ADS_PROTO_H_ > #define _LIBADS_ADS_PROTO_H_ > >+enum ads_sasl_state_e { >+ ADS_SASL_PLAIN = 0, >+ ADS_SASL_SIGN, >+ ADS_SASL_SEAL, >+}; >+ > /* The following definitions come from libads/ads_struct.c */ > > char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse); >@@ -39,7 +45,8 @@ char *ads_build_dn(const char *realm); > char *ads_build_domain(const char *dn); > ADS_STRUCT *ads_init(const char *realm, > const char *workgroup, >- const char *ldap_server); >+ const char *ldap_server, >+ enum ads_sasl_state_e sasl_state); > bool ads_set_sasl_wrap_flags(ADS_STRUCT *ads, int flags); > void ads_destroy(ADS_STRUCT **ads); > >diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c >index 3ab682c0e38..043a1b21247 100644 >--- a/source3/libads/ads_struct.c >+++ b/source3/libads/ads_struct.c >@@ -132,7 +132,8 @@ char *ads_build_domain(const char *dn) > */ > ADS_STRUCT *ads_init(const char *realm, > const char *workgroup, >- const char *ldap_server) >+ const char *ldap_server, >+ enum ads_sasl_state_e sasl_state) > { > ADS_STRUCT *ads; > int wrap_flags; >@@ -152,6 +153,17 @@ ADS_STRUCT *ads_init(const char *realm, > wrap_flags = 0; > } > >+ switch (sasl_state) { >+ case ADS_SASL_PLAIN: >+ break; >+ case ADS_SASL_SIGN: >+ wrap_flags |= ADS_AUTH_SASL_SIGN; >+ break; >+ case ADS_SASL_SEAL: >+ wrap_flags |= ADS_AUTH_SASL_SEAL; >+ break; >+ } >+ > ads->auth.flags = wrap_flags; > > /* Start with the configured page size when the connection is new, >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index 66aea348e23..2dc204f1ae8 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -2966,7 +2966,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) > > if ( !ads->ldap.ld ) { > if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, >- ads->server.ldap_server )) == NULL ) >+ ads->server.ldap_server, ADS_SASL_PLAIN )) == NULL ) > { > status = ADS_ERROR(LDAP_NO_MEMORY); > goto done; >@@ -3028,7 +3028,7 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32_t *val) > > if ( !ads->ldap.ld ) { > if ( (ads_s = ads_init( ads->server.realm, ads->server.workgroup, >- ads->server.ldap_server )) == NULL ) >+ ads->server.ldap_server, ADS_SASL_PLAIN )) == NULL ) > { > status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); > goto done; >diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c >index b876d7ea89f..a512afc238a 100644 >--- a/source3/libnet/libnet_join.c >+++ b/source3/libnet/libnet_join.c >@@ -140,7 +140,8 @@ static ADS_STATUS libnet_connect_ads(const char *dns_domain_name, > > my_ads = ads_init(dns_domain_name, > netbios_domain_name, >- dc_name); >+ dc_name, >+ ADS_SASL_SEAL); > if (!my_ads) { > return ADS_ERROR_LDAP(LDAP_NO_MEMORY); > } >diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c >index 4ee5b5278e4..f63dde61603 100644 >--- a/source3/libsmb/namequery_dc.c >+++ b/source3/libsmb/namequery_dc.c >@@ -69,7 +69,7 @@ static bool ads_dc_name(const char *domain, > > /* Try this 3 times then give up. */ > for( i =0 ; i < 3; i++) { >- ads = ads_init(realm, domain, NULL); >+ ads = ads_init(realm, domain, NULL, ADS_SASL_PLAIN); > if (!ads) { > TALLOC_FREE(sitename); > return False; >diff --git a/source3/printing/nt_printing_ads.c b/source3/printing/nt_printing_ads.c >index 2588e1de7e7..a82f1361fc8 100644 >--- a/source3/printing/nt_printing_ads.c >+++ b/source3/printing/nt_printing_ads.c >@@ -227,7 +227,7 @@ WERROR nt_printer_guid_retrieve(TALLOC_CTX *mem_ctx, const char *printer, > return WERR_NOT_ENOUGH_MEMORY; > } > >- ads = ads_init(lp_realm(), lp_workgroup(), NULL); >+ ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN); > if (ads == NULL) { > result = WERR_RPC_S_SERVER_UNAVAILABLE; > goto out; >@@ -577,7 +577,7 @@ WERROR nt_printer_publish(TALLOC_CTX *mem_ctx, > > TALLOC_FREE(sinfo2); > >- ads = ads_init(lp_realm(), lp_workgroup(), NULL); >+ ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN); > if (!ads) { > DEBUG(3, ("ads_init() failed\n")); > win_rc = WERR_RPC_S_SERVER_UNAVAILABLE; >@@ -633,7 +633,7 @@ WERROR check_published_printers(struct messaging_context *msg_ctx) > tmp_ctx = talloc_new(NULL); > if (!tmp_ctx) return WERR_NOT_ENOUGH_MEMORY; > >- ads = ads_init(lp_realm(), lp_workgroup(), NULL); >+ ads = ads_init(lp_realm(), lp_workgroup(), NULL, ADS_SASL_PLAIN); > if (!ads) { > DEBUG(3, ("ads_init() failed\n")); > return WERR_RPC_S_SERVER_UNAVAILABLE; >diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c >index 4a0f59a1e80..19ac9e4533f 100644 >--- a/source3/utils/net_ads.c >+++ b/source3/utils/net_ads.c >@@ -620,7 +620,10 @@ retry_connect: > realm = assume_own_realm(c); > } > >- ads = ads_init(realm, c->opt_target_workgroup, c->opt_host); >+ ads = ads_init(realm, >+ c->opt_target_workgroup, >+ c->opt_host, >+ ADS_SASL_PLAIN); > > if (!c->opt_user_name) { > c->opt_user_name = "administrator"; >@@ -729,7 +732,8 @@ static int net_ads_check_int(const char *realm, const char *workgroup, const cha > ADS_STRUCT *ads; > ADS_STATUS status; > >- if ( (ads = ads_init( realm, workgroup, host )) == NULL ) { >+ ads = ads_init(realm, workgroup, host, ADS_SASL_PLAIN); >+ if (ads == NULL ) { > return -1; > } > >@@ -1764,7 +1768,7 @@ static void _net_ads_join_dns_updates(struct net_context *c, TALLOC_CTX *ctx, st > * kinit with the machine password to do dns update. > */ > >- ads_dns = ads_init(lp_realm(), NULL, r->in.dc_name); >+ ads_dns = ads_init(lp_realm(), NULL, r->in.dc_name, ADS_SASL_PLAIN); > > if (ads_dns == NULL) { > d_fprintf(stderr, _("DNS update failed: out of memory!\n")); >@@ -2655,7 +2659,8 @@ static int net_ads_password(struct net_context *c, int argc, const char **argv) > > /* use the realm so we can eventually change passwords for users > in realms other than default */ >- if (!(ads = ads_init(realm, c->opt_workgroup, c->opt_host))) { >+ ads = ads_init(realm, c->opt_workgroup, c->opt_host, ADS_SASL_PLAIN); >+ if (ads == NULL) { > return -1; > } > >diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c >index 485ca831be9..20f47eb5954 100644 >--- a/source3/winbindd/winbindd_ads.c >+++ b/source3/winbindd/winbindd_ads.c >@@ -110,7 +110,10 @@ static ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp, > /* we don't want this to affect the users ccache */ > setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); > >- ads = ads_init(target_realm, target_dom_name, ldap_server); >+ ads = ads_init(target_realm, >+ target_dom_name, >+ ldap_server, >+ ADS_SASL_SEAL); > if (!ads) { > DEBUG(1,("ads_init for domain %s failed\n", target_dom_name)); > return ADS_ERROR(LDAP_NO_MEMORY); >diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c >index b9a1c1eda7b..0e671ca22be 100644 >--- a/source3/winbindd/winbindd_cm.c >+++ b/source3/winbindd/winbindd_cm.c >@@ -1414,7 +1414,10 @@ static bool dcip_check_name(TALLOC_CTX *mem_ctx, > > print_sockaddr(addr, sizeof(addr), pss); > >- ads = ads_init(domain->alt_name, domain->name, addr); >+ ads = ads_init(domain->alt_name, >+ domain->name, >+ addr, >+ ADS_SASL_PLAIN); > ads->auth.flags |= ADS_AUTH_NO_BIND; > ads->config.flags |= request_flags; > ads->server.no_fallback = true; >-- >2.17.1 > > >From 96ee2408f5ca85d84e341d642848a2532661a1f5 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 13 Aug 2019 16:30:07 +0200 >Subject: [PATCH 243/376] s3:libads: Cleanup error code paths in > ads_create_machine_acct() > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 8ed993789f93624b7b60dd5314fe5472e69e903a) >--- > source3/libads/ldap.c | 34 +++++++++++++++++++++++----------- > 1 file changed, 23 insertions(+), 11 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index 2dc204f1ae8..a0bc5fe6741 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -2092,11 +2092,12 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > uint32_t etype_list) > { > ADS_STATUS ret; >- char *samAccountName, *controlstr; >- TALLOC_CTX *ctx; >+ char *samAccountName = NULL; >+ char *controlstr = NULL; >+ TALLOC_CTX *ctx = NULL; > ADS_MODLIST mods; > char *machine_escaped = NULL; >- char *new_dn; >+ char *new_dn = NULL; > const char *objectClass[] = {"top", "person", "organizationalPerson", > "user", "computer", NULL}; > LDAPMessage *res = NULL; >@@ -2110,13 +2111,14 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > return ret; > } > >- if (!(ctx = talloc_init("ads_add_machine_acct"))) >+ ctx = talloc_init("ads_add_machine_acct"); >+ if (ctx == NULL) { > return ADS_ERROR(LDAP_NO_MEMORY); >- >- ret = ADS_ERROR(LDAP_NO_MEMORY); >+ } > > machine_escaped = escape_rdn_val_string_alloc(machine_name); >- if (!machine_escaped) { >+ if (machine_escaped == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >@@ -2131,17 +2133,26 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > ads_msgfree(ads, res); > > new_dn = talloc_asprintf(ctx, "cn=%s,%s", machine_escaped, org_unit); >- samAccountName = talloc_asprintf(ctx, "%s$", machine_name); >+ if (new_dn == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } > >- if ( !new_dn || !samAccountName ) { >+ samAccountName = talloc_asprintf(ctx, "%s$", machine_name); >+ if (samAccountName == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >- if (!(controlstr = talloc_asprintf(ctx, "%u", acct_control))) { >+ controlstr = talloc_asprintf(ctx, "%u", acct_control); >+ if (controlstr == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >- if (!(mods = ads_init_mods(ctx))) { >+ mods = ads_init_mods(ctx); >+ if (mods == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >@@ -2155,6 +2166,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > > etype_list_str = talloc_asprintf(ctx, "%d", (int)etype_list); > if (etype_list_str == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > ads_mod_str(ctx, &mods, "msDS-SupportedEncryptionTypes", >-- >2.17.1 > > >From 023a59d4262c1de4b0d62de0c75a905c0ea658e8 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 21 Aug 2019 12:22:32 +0200 >Subject: [PATCH 244/376] s3:libads: Use a talloc_asprintf in > ads_find_machine_acct() > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 35f3e4aed1f1c2ba1c8dc50921f238937f343357) >--- > source3/libads/ldap.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index a0bc5fe6741..f799c8f45d8 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -1367,18 +1367,22 @@ char *ads_parent_dn(const char *dn) > ADS_STATUS status; > char *expr; > const char *attrs[] = {"*", "msDS-SupportedEncryptionTypes", "nTSecurityDescriptor", NULL}; >+ TALLOC_CTX *frame = talloc_stackframe(); > > *res = NULL; > > /* the easiest way to find a machine account anywhere in the tree > is to look for hostname$ */ >- if (asprintf(&expr, "(samAccountName=%s$)", machine) == -1) { >- DEBUG(1, ("asprintf failed!\n")); >- return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); >+ expr = talloc_asprintf(frame, "(samAccountName=%s$)", machine); >+ if (expr == NULL) { >+ status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); >+ goto done; > } > > status = ads_search(ads, res, expr, attrs); >- SAFE_FREE(expr); >+ >+done: >+ TALLOC_FREE(frame); > return status; > } > >-- >2.17.1 > > >From 8cc6e035b6e68267d608e1d727d6e66b92823655 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 14 Aug 2019 13:01:19 +0200 >Subject: [PATCH 245/376] s3:libads: Fix detection if acount already exists in > ads_find_machine_count() > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 4f389c1f78cdc2424795e3b2a1ce43818c400c2d) >--- > source3/libads/ldap.c | 36 ++++++++++++++++++++++++++++-------- > 1 file changed, 28 insertions(+), 8 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index f799c8f45d8..ea0d79a3600 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -1366,7 +1366,21 @@ char *ads_parent_dn(const char *dn) > { > ADS_STATUS status; > char *expr; >- const char *attrs[] = {"*", "msDS-SupportedEncryptionTypes", "nTSecurityDescriptor", NULL}; >+ const char *attrs[] = { >+ /* This is how Windows checks for machine accounts */ >+ "objectClass", >+ "SamAccountName", >+ "userAccountControl", >+ "DnsHostName", >+ "ServicePrincipalName", >+ "unicodePwd", >+ >+ /* Additional attributes Samba checks */ >+ "msDS-SupportedEncryptionTypes", >+ "nTSecurityDescriptor", >+ >+ NULL >+ }; > TALLOC_CTX *frame = talloc_stackframe(); > > *res = NULL; >@@ -1380,6 +1394,11 @@ char *ads_parent_dn(const char *dn) > } > > status = ads_search(ads, res, expr, attrs); >+ if (ADS_ERR_OK(status)) { >+ if (ads_count_replies(ads, *res) != 1) { >+ status = ADS_ERROR_LDAP(LDAP_NO_SUCH_OBJECT); >+ } >+ } > > done: > TALLOC_FREE(frame); >@@ -1867,11 +1886,11 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin > char *dn_string = NULL; > > ret = ads_find_machine_acct(ads, &res, machine_name); >- if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { >+ if (!ADS_ERR_OK(ret)) { > DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name)); > DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name)); > ads_msgfree(ads, res); >- return ADS_ERROR(LDAP_NO_SUCH_OBJECT); >+ return ret; > } > > DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name)); >@@ -2027,12 +2046,12 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, > const char **servicePrincipalName = spns; > > ret = ads_find_machine_acct(ads, &res, machine_name); >- if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) { >+ if (!ADS_ERR_OK(ret)) { > DEBUG(1,("ads_add_service_principal_name: WARNING: Host Account for %s not found... skipping operation.\n", > machine_name)); > DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principals have NOT been added.\n")); > ads_msgfree(ads, res); >- return ADS_ERROR(LDAP_NO_SUCH_OBJECT); >+ return ret; > } > > DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name)); >@@ -2127,7 +2146,7 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > } > > ret = ads_find_machine_acct(ads, &res, machine_escaped); >- if (ADS_ERR_OK(ret) && ads_count_replies(ads, res) == 1) { >+ if (ADS_ERR_OK(ret)) { > DBG_DEBUG("Host account for %s already exists.\n", > machine_escaped); > ret = ADS_ERROR_LDAP(LDAP_ALREADY_EXISTS); >@@ -3688,14 +3707,15 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) > TALLOC_FREE(hostnameDN); > > status = ads_find_machine_acct(ads, &res, host); >- if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { >+ if ((status.error_type == ENUM_ADS_ERROR_LDAP) && >+ (status.err.rc != LDAP_NO_SUCH_OBJECT)) { > DEBUG(3, ("Failed to remove host account.\n")); > SAFE_FREE(host); > return status; > } > > SAFE_FREE(host); >- return status; >+ return ADS_SUCCESS; > } > > /** >-- >2.17.1 > > >From e0be43a863bba4be3df81b8a7b7a95f99bfb4783 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 14 Aug 2019 12:17:20 +0200 >Subject: [PATCH 246/376] s3:libads: Don't set supported encryption types > during account creation > >This is already handled by libnet_join_post_processing_ads_modify() >which calls libnet_join_set_etypes() if encrytion types should be set. > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit b755a6438022579dab1a403c81d60b1ed7efca38) >--- > source3/libads/ldap.c | 18 ------------------ > 1 file changed, 18 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index ea0d79a3600..cdefe290c28 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -2127,12 +2127,6 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > uint32_t acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ > UF_DONT_EXPIRE_PASSWD |\ > UF_ACCOUNTDISABLE ); >- uint32_t func_level = 0; >- >- ret = ads_domain_func_level(ads, &func_level); >- if (!ADS_ERR_OK(ret)) { >- return ret; >- } > > ctx = talloc_init("ads_add_machine_acct"); > if (ctx == NULL) { >@@ -2184,18 +2178,6 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > ads_mod_strlist(ctx, &mods, "objectClass", objectClass); > ads_mod_str(ctx, &mods, "userAccountControl", controlstr); > >- if (func_level >= DS_DOMAIN_FUNCTION_2008) { >- const char *etype_list_str; >- >- etype_list_str = talloc_asprintf(ctx, "%d", (int)etype_list); >- if (etype_list_str == NULL) { >- ret = ADS_ERROR(LDAP_NO_MEMORY); >- goto done; >- } >- ads_mod_str(ctx, &mods, "msDS-SupportedEncryptionTypes", >- etype_list_str); >- } >- > ret = ads_gen_add(ads, new_dn, mods); > > done: >-- >2.17.1 > > >From 86e86cddcb5b6e0319605e1c46fe1932b3e81bf1 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Tue, 13 Aug 2019 16:34:34 +0200 >Subject: [PATCH 247/376] s3:libads: Fix creating machine account using LDAP > >This implements the same behaviour as Windows. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13884 > >Pair-Programmed-With: Guenther Deschner <gd@samba.org> >Signed-off-by: Guenther Deschner <gd@samba.org> >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit ce7762935051c862ecdd3e82d93096aac61dd292) >--- > source3/libads/ads_proto.h | 4 +- > source3/libads/ldap.c | 118 +++++++++++++++++++++++++++++++---- > source3/libnet/libnet_join.c | 23 ++++--- > 3 files changed, 124 insertions(+), 21 deletions(-) > >diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h >index 92bb3a22cdb..495ef5d3325 100644 >--- a/source3/libads/ads_proto.h >+++ b/source3/libads/ads_proto.h >@@ -114,8 +114,10 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, const char *machine_ > const char **spns); > ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > const char *machine_name, >+ const char *machine_password, > const char *org_unit, >- uint32_t etype_list); >+ uint32_t etype_list, >+ const char *dns_domain_name); > ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name, > const char *org_unit, bool *moved); > int ads_count_replies(ADS_STRUCT *ads, void *res); >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index cdefe290c28..928c0da5af9 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -1516,7 +1516,6 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods, > name, (const void **) vals); > } > >-#if 0 > /** > * Add a single ber-encoded value to a mod list > * @param ctx An initialized TALLOC_CTX >@@ -1537,7 +1536,6 @@ static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, > return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES, > name, (const void **) values); > } >-#endif > > static void ads_print_error(int ret, LDAP *ld) > { >@@ -2111,8 +2109,10 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, > > ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > const char *machine_name, >+ const char *machine_password, > const char *org_unit, >- uint32_t etype_list) >+ uint32_t etype_list, >+ const char *dns_domain_name) > { > ADS_STATUS ret; > char *samAccountName = NULL; >@@ -2120,13 +2120,23 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > TALLOC_CTX *ctx = NULL; > ADS_MODLIST mods; > char *machine_escaped = NULL; >+ char *dns_hostname = NULL; > char *new_dn = NULL; >- const char *objectClass[] = {"top", "person", "organizationalPerson", >- "user", "computer", NULL}; >+ char *utf8_pw = NULL; >+ size_t utf8_pw_len = 0; >+ char *utf16_pw = NULL; >+ size_t utf16_pw_len = 0; >+ struct berval machine_pw_val; >+ bool ok; >+ const char **spn_array = NULL; >+ size_t num_spns = 0; >+ const char *spn_prefix[] = { >+ "HOST", >+ "RestrictedKrbHost", >+ }; >+ size_t i; > LDAPMessage *res = NULL; >- uint32_t acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\ >- UF_DONT_EXPIRE_PASSWD |\ >- UF_ACCOUNTDISABLE ); >+ uint32_t acct_control = UF_WORKSTATION_TRUST_ACCOUNT; > > ctx = talloc_init("ads_add_machine_acct"); > if (ctx == NULL) { >@@ -2139,10 +2149,9 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > goto done; > } > >+ /* Check if the machine account already exists. */ > ret = ads_find_machine_acct(ads, &res, machine_escaped); > if (ADS_ERR_OK(ret)) { >- DBG_DEBUG("Host account for %s already exists.\n", >- machine_escaped); > ret = ADS_ERROR_LDAP(LDAP_ALREADY_EXISTS); > ads_msgfree(ads, res); > goto done; >@@ -2155,28 +2164,111 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > goto done; > } > >+ /* Create machine account */ >+ > samAccountName = talloc_asprintf(ctx, "%s$", machine_name); > if (samAccountName == NULL) { > ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >+ dns_hostname = talloc_asprintf(ctx, >+ "%s.%s", >+ machine_name, >+ dns_domain_name); >+ if (dns_hostname == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ /* Add dns_hostname SPNs */ >+ for (i = 0; i < ARRAY_SIZE(spn_prefix); i++) { >+ char *spn = talloc_asprintf(ctx, >+ "%s/%s", >+ spn_prefix[i], >+ dns_hostname); >+ if (spn == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ ok = add_string_to_array(spn_array, >+ spn, >+ &spn_array, >+ &num_spns); >+ if (!ok) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ } >+ >+ /* Add machine_name SPNs */ >+ for (i = 0; i < ARRAY_SIZE(spn_prefix); i++) { >+ char *spn = talloc_asprintf(ctx, >+ "%s/%s", >+ spn_prefix[i], >+ machine_name); >+ if (spn == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ ok = add_string_to_array(spn_array, >+ spn, >+ &spn_array, >+ &num_spns); >+ if (!ok) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ } >+ >+ /* Make sure to NULL terminate the array */ >+ spn_array = talloc_realloc(ctx, spn_array, const char *, num_spns + 1); >+ if (spn_array == NULL) { >+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); >+ } >+ spn_array[num_spns] = NULL; >+ > controlstr = talloc_asprintf(ctx, "%u", acct_control); > if (controlstr == NULL) { > ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >+ utf8_pw = talloc_asprintf(ctx, "\"%s\"", machine_password); >+ if (utf8_pw == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ utf8_pw_len = strlen(utf8_pw); >+ >+ ok = convert_string_talloc(ctx, >+ CH_UTF8, CH_UTF16MUNGED, >+ utf8_pw, utf8_pw_len, >+ (void *)&utf16_pw, &utf16_pw_len); >+ if (!ok) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ machine_pw_val = (struct berval) { >+ .bv_val = utf16_pw, >+ .bv_len = utf16_pw_len, >+ }; >+ > mods = ads_init_mods(ctx); > if (mods == NULL) { > ret = ADS_ERROR(LDAP_NO_MEMORY); > goto done; > } > >- ads_mod_str(ctx, &mods, "cn", machine_name); >- ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName); >- ads_mod_strlist(ctx, &mods, "objectClass", objectClass); >+ ads_mod_str(ctx, &mods, "objectClass", "Computer"); >+ ads_mod_str(ctx, &mods, "SamAccountName", samAccountName); > ads_mod_str(ctx, &mods, "userAccountControl", controlstr); >+ ads_mod_str(ctx, &mods, "DnsHostName", dns_hostname); >+ ads_mod_strlist(ctx, &mods, "ServicePrincipalName", spn_array); >+ ads_mod_ber(ctx, &mods, "unicodePwd", &machine_pw_val); > > ret = ads_gen_add(ads, new_dn, mods); > >diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c >index a512afc238a..d5c8599beee 100644 >--- a/source3/libnet/libnet_join.c >+++ b/source3/libnet/libnet_join.c >@@ -338,10 +338,22 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, > /* Attempt to create the machine account and bail if this fails. > Assume that the admin wants exactly what they requested */ > >+ if (r->in.machine_password == NULL) { >+ r->in.machine_password = >+ trust_pw_new_value(mem_ctx, >+ r->in.secure_channel_type, >+ SEC_ADS); >+ if (r->in.machine_password == NULL) { >+ return ADS_ERROR_LDAP(LDAP_NO_MEMORY); >+ } >+ } >+ > status = ads_create_machine_acct(r->in.ads, > r->in.machine_name, >+ r->in.machine_password, > r->in.account_ou, >- r->in.desired_encryption_types); >+ r->in.desired_encryption_types, >+ r->out.dns_domain_name); > > if (ADS_ERR_OK(status)) { > DEBUG(1,("machine account creation created\n")); >@@ -2668,12 +2680,11 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, > if (ADS_ERR_OK(ads_status)) { > > /* >- * LDAP object create succeeded, now go to the rpc >- * password set routines >+ * LDAP object creation succeeded. > */ >- > r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE; >- goto rpc_join; >+ >+ return WERR_OK; > } > > if (initial_account_ou != NULL) { >@@ -2687,8 +2698,6 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx, > DBG_INFO("Failed to pre-create account in OU %s: %s\n", > r->in.account_ou, ads_errstr(ads_status)); > } >- rpc_join: >- > #endif /* HAVE_ADS */ > > if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE) && >-- >2.17.1 > > >From 8fa84176dbcc268492f07f92d8baf3156877f78a Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Wed, 14 Aug 2019 10:15:19 +0200 >Subject: [PATCH 248/376] s3:libnet: Improve debug messages > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 39b8c8b30a5d5bd70f8da3a02cf77f7592788b94) >--- > source3/libnet/libnet_join.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c >index d5c8599beee..31d1d221ed3 100644 >--- a/source3/libnet/libnet_join.c >+++ b/source3/libnet/libnet_join.c >@@ -356,7 +356,7 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, > r->out.dns_domain_name); > > if (ADS_ERR_OK(status)) { >- DEBUG(1,("machine account creation created\n")); >+ DBG_WARNING("Machine account successfully created\n"); > return status; > } else if ((status.error_type == ENUM_ADS_ERROR_LDAP) && > (status.err.rc == LDAP_ALREADY_EXISTS)) { >@@ -364,7 +364,7 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx, > } > > if (!ADS_ERR_OK(status)) { >- DEBUG(1,("machine account creation failed\n")); >+ DBG_WARNING("Failed to create machine account\n"); > return status; > } > >-- >2.17.1 > > >From 440c8890798d6ac7a75f41f0ea0d1f98d234eb6b Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Thu, 8 Aug 2019 14:40:04 +0200 >Subject: [PATCH 249/376] s3:libads: Just change the machine password if > account already exists > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13884 > >Pair-Programmed-With: Guenther Deschner <gd@samba.org> >Signed-off-by: Guenther Deschner <gd@samba.org> >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> >(cherry picked from commit 14f320fa1e40ecc3a43dabb0cecd57430270a521) >--- > source3/libads/ldap.c | 167 ++++++++++++++++++++++++++++++----- > source3/libnet/libnet_join.c | 1 + > 2 files changed, 146 insertions(+), 22 deletions(-) > >diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c >index 928c0da5af9..979192eb3ed 100644 >--- a/source3/libads/ldap.c >+++ b/source3/libads/ldap.c >@@ -2098,6 +2098,127 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, > return ret; > } > >+static uint32_t ads_get_acct_ctrl(ADS_STRUCT *ads, >+ LDAPMessage *msg) >+{ >+ uint32_t acct_ctrl = 0; >+ bool ok; >+ >+ ok = ads_pull_uint32(ads, msg, "userAccountControl", &acct_ctrl); >+ if (!ok) { >+ return 0; >+ } >+ >+ return acct_ctrl; >+} >+ >+static ADS_STATUS ads_change_machine_acct(ADS_STRUCT *ads, >+ LDAPMessage *msg, >+ const struct berval *machine_pw_val) >+{ >+ ADS_MODLIST mods; >+ ADS_STATUS ret; >+ TALLOC_CTX *frame = talloc_stackframe(); >+ uint32_t acct_control; >+ char *control_str = NULL; >+ const char *attrs[] = { >+ "objectSid", >+ NULL >+ }; >+ LDAPMessage *res = NULL; >+ char *dn = NULL; >+ >+ dn = ads_get_dn(ads, frame, msg); >+ if (dn == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ acct_control = ads_get_acct_ctrl(ads, msg); >+ if (acct_control == 0) { >+ ret = ADS_ERROR(LDAP_NO_RESULTS_RETURNED); >+ goto done; >+ } >+ >+ /* >+ * Changing the password, disables the account. So we need to change the >+ * userAccountControl flags to enable it again. >+ */ >+ mods = ads_init_mods(frame); >+ if (mods == NULL) { >+ ret = ADS_ERROR_LDAP(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ ads_mod_ber(frame, &mods, "unicodePwd", machine_pw_val); >+ >+ ret = ads_gen_mod(ads, dn, mods); >+ if (!ADS_ERR_OK(ret)) { >+ goto done; >+ } >+ TALLOC_FREE(mods); >+ >+ /* >+ * To activate the account, we need to disable and enable it. >+ */ >+ acct_control |= UF_ACCOUNTDISABLE; >+ >+ control_str = talloc_asprintf(frame, "%u", acct_control); >+ if (control_str == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ mods = ads_init_mods(frame); >+ if (mods == NULL) { >+ ret = ADS_ERROR_LDAP(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ ads_mod_str(frame, &mods, "userAccountControl", control_str); >+ >+ ret = ads_gen_mod(ads, dn, mods); >+ if (!ADS_ERR_OK(ret)) { >+ goto done; >+ } >+ TALLOC_FREE(mods); >+ TALLOC_FREE(control_str); >+ >+ /* >+ * Enable the account again. >+ */ >+ acct_control &= ~UF_ACCOUNTDISABLE; >+ >+ control_str = talloc_asprintf(frame, "%u", acct_control); >+ if (control_str == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ mods = ads_init_mods(frame); >+ if (mods == NULL) { >+ ret = ADS_ERROR_LDAP(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ ads_mod_str(frame, &mods, "userAccountControl", control_str); >+ >+ ret = ads_gen_mod(ads, dn, mods); >+ if (!ADS_ERR_OK(ret)) { >+ goto done; >+ } >+ TALLOC_FREE(mods); >+ TALLOC_FREE(control_str); >+ >+ ret = ads_search_dn(ads, &res, dn, attrs); >+ ads_msgfree(ads, res); >+ >+done: >+ talloc_free(frame); >+ >+ return ret; >+} >+ > /** > * adds a machine account to the ADS server > * @param ads An intialized ADS_STRUCT >@@ -2149,11 +2270,34 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > goto done; > } > >+ utf8_pw = talloc_asprintf(ctx, "\"%s\"", machine_password); >+ if (utf8_pw == NULL) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ utf8_pw_len = strlen(utf8_pw); >+ >+ ok = convert_string_talloc(ctx, >+ CH_UTF8, CH_UTF16MUNGED, >+ utf8_pw, utf8_pw_len, >+ (void *)&utf16_pw, &utf16_pw_len); >+ if (!ok) { >+ ret = ADS_ERROR(LDAP_NO_MEMORY); >+ goto done; >+ } >+ >+ machine_pw_val = (struct berval) { >+ .bv_val = utf16_pw, >+ .bv_len = utf16_pw_len, >+ }; >+ > /* Check if the machine account already exists. */ > ret = ads_find_machine_acct(ads, &res, machine_escaped); > if (ADS_ERR_OK(ret)) { >- ret = ADS_ERROR_LDAP(LDAP_ALREADY_EXISTS); >+ /* Change the machine account password */ >+ ret = ads_change_machine_acct(ads, res, &machine_pw_val); > ads_msgfree(ads, res); >+ > goto done; > } > ads_msgfree(ads, res); >@@ -2236,27 +2380,6 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads, > goto done; > } > >- utf8_pw = talloc_asprintf(ctx, "\"%s\"", machine_password); >- if (utf8_pw == NULL) { >- ret = ADS_ERROR(LDAP_NO_MEMORY); >- goto done; >- } >- utf8_pw_len = strlen(utf8_pw); >- >- ok = convert_string_talloc(ctx, >- CH_UTF8, CH_UTF16MUNGED, >- utf8_pw, utf8_pw_len, >- (void *)&utf16_pw, &utf16_pw_len); >- if (!ok) { >- ret = ADS_ERROR(LDAP_NO_MEMORY); >- goto done; >- } >- >- machine_pw_val = (struct berval) { >- .bv_val = utf16_pw, >- .bv_len = utf16_pw_len, >- }; >- > mods = ads_init_mods(ctx); > if (mods == NULL) { > ret = ADS_ERROR(LDAP_NO_MEMORY); >diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c >index 31d1d221ed3..1052afde641 100644 >--- a/source3/libnet/libnet_join.c >+++ b/source3/libnet/libnet_join.c >@@ -968,6 +968,7 @@ static ADS_STATUS libnet_join_post_processing_ads_modify(TALLOC_CTX *mem_ctx, > > if (r->in.ads->auth.ccache_name != NULL) { > ads_kdestroy(r->in.ads->auth.ccache_name); >+ r->in.ads->auth.ccache_name = NULL; > } > > ads_destroy(&r->in.ads); >-- >2.17.1 > > >From 8d426b146e7f9ba04dc07779d810bd7c8fcd4b10 Mon Sep 17 00:00:00 2001 >From: Andreas Schneider <asn@samba.org> >Date: Thu, 22 Aug 2019 16:31:30 +0200 >Subject: [PATCH 250/376] testprogs: Add test for 'net ads join > createcomputer=' > >Signed-off-by: Andreas Schneider <asn@samba.org> >Reviewed-by: Alexander Bokovoy <ab@samba.org> > >Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> >Autobuild-Date(master): Wed Oct 9 08:26:17 UTC 2019 on sn-devel-184 > >(cherry picked from commit 459b43e5776180dc1540cd845b72ff78747ecd6f) >--- > testprogs/blackbox/test_net_ads.sh | 32 ++++++++++++++++++++++++++++-- > 1 file changed, 30 insertions(+), 2 deletions(-) > >diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh >index 512aa9d2952..cc8345c4624 100755 >--- a/testprogs/blackbox/test_net_ads.sh >+++ b/testprogs/blackbox/test_net_ads.sh >@@ -31,6 +31,16 @@ if [ -x "$BINDIR/ldbsearch" ]; then > ldbsearch="$BINDIR/ldbsearch" > fi > >+ldbadd="ldbadd" >+if [ -x "$BINDIR/ldbadd" ]; then >+ ldbadd="$BINDIR/ldbadd" >+fi >+ >+ldbdel="ldbdel" >+if [ -x "$BINDIR/ldbdel" ]; then >+ ldbdel="$BINDIR/ldbdel" >+fi >+ > # Load test functions > . `dirname $0`/subunit.sh > >@@ -188,8 +198,9 @@ testit "testjoin user+password" $VALGRIND $net_tool ads testjoin -U$DC_USERNAME% > > testit "leave+keep_account" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD --keep-account || failed=`expr $failed + 1` > >-computers_ldb_ou="CN=Computers,DC=addom,DC=samba,DC=example,DC=com" >-testit "ldb check for existence of machine account" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "cn=$HOSTNAME,$computers_ldb_ou" || failed=`expr $failed + 1` >+base_dn="DC=addom,DC=samba,DC=example,DC=com" >+computers_dn="CN=Computers,$base_dn" >+testit "ldb check for existence of machine account" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "cn=$HOSTNAME,$computers_dn" || failed=`expr $failed + 1` > > testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` > >@@ -198,6 +209,23 @@ testit "testjoin" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1` > ##Goodbye... > testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` > >+# >+# Test createcomputer option of 'net ads join' >+# >+testit "Create OU=Servers,$base_dn" $VALGRIND $ldbadd -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER <<EOF >+dn: OU=Servers,$base_dn >+objectClass: organizationalUnit >+EOF >+ >+testit "join+createcomputer" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD createcomputer=Servers || failed=`expr $failed + 1` >+ >+testit "ldb check for existence of machine account in OU=Servers" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "cn=$HOSTNAME,OU=Servers,$base_dn" || failed=`expr $failed + 1` >+ >+## Goodbye... >+testit "leave+createcomputer" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1` >+ >+testit "Remove OU=Servers" $VALGRIND $ldbdel -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER "OU=Servers,$base_dn" >+ > rm -rf $BASEDIR/$WORKDIR > > exit $failed >-- >2.17.1 > > >From 8f4603fdc4e096cfdfd6aa998b0aa399acb3a5b8 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org> >Date: Wed, 25 Sep 2019 23:44:49 +0200 >Subject: [PATCH 251/376] libcli/auth: add test for gensec_schannel code > >Guenther > >Signed-off-by: Guenther Deschner <gd@samba.org> >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 7eae4280d23404be7d27f65a0c817bea2e0084b6) >--- > libcli/auth/tests/test_schannel.c | 305 ++++++++++++++++++++++++++++++ > libcli/auth/wscript_build | 8 + > selftest/knownfail | 1 + > selftest/tests.py | 2 + > 4 files changed, 316 insertions(+) > create mode 100644 libcli/auth/tests/test_schannel.c > >diff --git a/libcli/auth/tests/test_schannel.c b/libcli/auth/tests/test_schannel.c >new file mode 100644 >index 00000000000..b1c88fdf667 >--- /dev/null >+++ b/libcli/auth/tests/test_schannel.c >@@ -0,0 +1,305 @@ >+/* >+ * Unix SMB/CIFS implementation. >+ * >+ * Copyright (C) 2019 Guenther Deschner <gd@samba.org> >+ * >+ * This program is free software; you can redistribute it and/or modify >+ * it under the terms of the GNU General Public License as published by >+ * the Free Software Foundation; either version 3 of the License, or >+ * (at your option) any later version. >+ * >+ * This program is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ * GNU General Public License for more details. >+ * >+ * You should have received a copy of the GNU General Public License >+ * along with this program. If not, see <http://www.gnu.org/licenses/>. >+ */ >+ >+#include <stdarg.h> >+#include <stddef.h> >+#include <stdint.h> >+#include <setjmp.h> >+#include <cmocka.h> >+ >+#include "includes.h" >+#include "auth/gensec/schannel.c" >+ >+static void torture_schannel_seal_flags(void **state, uint32_t flags, >+ const DATA_BLOB session_key, >+ const DA