diff --git a/samba-4-21-fix-libldb-deepbind.patch b/samba-4-21-fix-libldb-deepbind.patch deleted file mode 100644 index 9593482..0000000 --- a/samba-4-21-fix-libldb-deepbind.patch +++ /dev/null @@ -1,286 +0,0 @@ -From e2d3bf09d6d75c7dc009aff36119e51ea59371fc Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Wed, 25 Sep 2024 09:19:17 +0200 -Subject: [PATCH 1/4] lib:ldb: Remove trailing spaces from ldb_modules.c - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15643 - -Signed-off-by: Andreas Schneider -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 8d6b5183770895fef002b6cce84902d1874fa502) ---- - lib/ldb/common/ldb_modules.c | 34 +++++++++++++++++----------------- - 1 file changed, 17 insertions(+), 17 deletions(-) - -diff --git a/lib/ldb/common/ldb_modules.c b/lib/ldb/common/ldb_modules.c -index b5627b0d04f..5c970626206 100644 ---- a/lib/ldb/common/ldb_modules.c -+++ b/lib/ldb/common/ldb_modules.c -@@ -631,9 +631,9 @@ int ldb_next_start_trans(struct ldb_module *module) - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "start_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } -- if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", -- ldb_errstring(module->ldb)); -+ if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_start_trans error: %s", -+ ldb_errstring(module->ldb)); - } - return ret; - } -@@ -650,9 +650,9 @@ int ldb_next_end_trans(struct ldb_module *module) - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "end_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } -- if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", -- ldb_errstring(module->ldb)); -+ if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_end_trans error: %s", -+ ldb_errstring(module->ldb)); - } - return ret; - } -@@ -720,9 +720,9 @@ int ldb_next_prepare_commit(struct ldb_module *module) - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "prepare_commit error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } -- if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", -- ldb_errstring(module->ldb)); -+ if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_prepare_commit error: %s", -+ ldb_errstring(module->ldb)); - } - return ret; - } -@@ -739,9 +739,9 @@ int ldb_next_del_trans(struct ldb_module *module) - /* Set a default error string, to place the blame somewhere */ - ldb_asprintf_errstring(module->ldb, "del_trans error in module %s: %s (%d)", module->ops->name, ldb_strerror(ret), ret); - } -- if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -- ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", -- ldb_errstring(module->ldb)); -+ if ((module && module->ldb->flags & LDB_FLG_ENABLE_TRACING)) { -+ ldb_debug(module->ldb, LDB_DEBUG_TRACE, "ldb_next_del_trans error: %s", -+ ldb_errstring(module->ldb)); - } - return ret; - } -@@ -777,17 +777,17 @@ int ldb_module_send_entry(struct ldb_request *req, - req->handle->nesting == 0) { - char *s; - struct ldb_ldif ldif; -- -+ - ldif.changetype = LDB_CHANGETYPE_NONE; - ldif.msg = discard_const_p(struct ldb_message, msg); - - ldb_debug_add(req->handle->ldb, "ldb_trace_response: ENTRY\n"); - -- /* -+ /* - * The choice to call - * ldb_ldif_write_redacted_trace_string() is CRITICAL - * for security. It ensures that we do not output -- * passwords into debug logs -+ * passwords into debug logs - */ - - s = ldb_ldif_write_redacted_trace_string(req->handle->ldb, msg, &ldif); -@@ -1104,8 +1104,8 @@ static int ldb_modules_load_dir(const char *modules_dir, const char *version) - return LDB_SUCCESS; - } - --/* -- load any additional modules from the given directory -+/* -+ load any additional modules from the given directory - */ - void ldb_set_modules_dir(struct ldb_context *ldb, const char *path) - { --- -2.46.1 - - -From d0ec464cfced2654d74672846d83c19f69af622b Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Wed, 25 Sep 2024 09:19:44 +0200 -Subject: [PATCH 2/4] lib:ldb: Don't use RTLD_DEEPBIND by default - -It should be off by default, as this is not needed by default. It -crashes named on startup, if bind is built with jemalloc support. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15643 - -Signed-off-by: Andreas Schneider -Reviewed-by: Stefan Metzmacher -(cherry picked from commit dc6927fdca2ad77dbcf212ef4d3ba0d118ec7bdf) ---- - lib/ldb/common/ldb_modules.c | 21 ++++++--------------- - selftest/selftest.pl | 6 ------ - selftest/wscript | 5 ++--- - 3 files changed, 8 insertions(+), 24 deletions(-) - -diff --git a/lib/ldb/common/ldb_modules.c b/lib/ldb/common/ldb_modules.c -index 5c970626206..08d251f9bdd 100644 ---- a/lib/ldb/common/ldb_modules.c -+++ b/lib/ldb/common/ldb_modules.c -@@ -945,7 +945,7 @@ static int ldb_modules_load_path(const char *path, const char *version) - int dlopen_flags; - - #ifdef RTLD_DEEPBIND -- bool deepbind_enabled = (getenv("LDB_MODULES_DISABLE_DEEPBIND") == NULL); -+ bool deepbind_enabled = (getenv("LDB_MODULES_ENABLE_DEEPBIND") != NULL); - #endif - - ret = stat(path, &st); -@@ -981,21 +981,12 @@ static int ldb_modules_load_path(const char *path, const char *version) - dlopen_flags = RTLD_NOW; - #ifdef RTLD_DEEPBIND - /* -- * use deepbind if possible, to avoid issues with different -- * system library variants, for example ldb modules may be linked -- * against Heimdal while the application may use MIT kerberos. -+ * On systems where e.g. different kerberos libraries are used, like a -+ * mix of Heimdal and MIT Kerberos, LDB_MODULES_ENABLE_DEEPBIND should -+ * be set to avoid issues. - * -- * See the dlopen manpage for details. -- * -- * One typical user is the bind_dlz module of Samba, -- * but symbol versioning might be enough... -- * -- * We need a way to disable this in order to allow the -- * ldb_*ldap modules to work with a preloaded socket wrapper. -- * -- * So in future we may remove this completely -- * or at least invert the default behavior. -- */ -+ * By default Linux distributions only have one Kerberos library. -+ */ - if (deepbind_enabled) { - dlopen_flags |= RTLD_DEEPBIND; - } -diff --git a/selftest/selftest.pl b/selftest/selftest.pl -index 26b1663b5b6..a0c4ec80f59 100755 ---- a/selftest/selftest.pl -+++ b/selftest/selftest.pl -@@ -433,12 +433,6 @@ $ENV{UID_WRAPPER} = 1; - # We are already hitting the limit, so double it. - $ENV{NSS_WRAPPER_MAX_HOSTENTS} = 200; - --# Disable RTLD_DEEPBIND hack for Samba bind dlz module --# --# This is needed in order to allow the ldb_*ldap module --# to work with a preloaded socket wrapper. --$ENV{LDB_MODULES_DISABLE_DEEPBIND} = 1; -- - my $socket_wrapper_dir; - if ($opt_socket_wrapper) { - $socket_wrapper_dir = SocketWrapper::setup_dir("$prefix_abs/w", $opt_socket_wrapper_pcap); -diff --git a/selftest/wscript b/selftest/wscript -index 52c34dcb88d..95e70706e63 100644 ---- a/selftest/wscript -+++ b/selftest/wscript -@@ -333,9 +333,8 @@ def cmd_testonly(opt): - asan_options += ":suppressions=${srcdir}/selftest/sanitizer/asan.supp" - asan_options += " " - -- # And we need to disable RTLD_DEEPBIND in ldb and socket wrapper -- no_leak_check = "LDB_MODULES_DISABLE_DEEPBIND=1 " -- no_leak_check += "SOCKET_WRAPPER_DISABLE_DEEP_BIND=1" -+ # We need to disable RTLD_DEEPBIND in socket wrapper -+ no_leak_check = "SOCKET_WRAPPER_DISABLE_DEEP_BIND=1" - no_leak_check += " " - env.CORE_COMMAND = asan_options + no_leak_check + env.CORE_COMMAND - --- -2.46.1 - - -From e6745b1444b28904258710dff1dddd18a8b9f662 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Wed, 25 Sep 2024 09:40:23 +0200 -Subject: [PATCH 3/4] lib:ldb: Remove trailing spaces from ldb.3.xml - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15643 - -Signed-off-by: Andreas Schneider -Reviewed-by: Stefan Metzmacher -(cherry picked from commit d6ff05cb5708fb6746176821bee5f713195efa54) ---- - lib/ldb/man/ldb.3.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/lib/ldb/man/ldb.3.xml b/lib/ldb/man/ldb.3.xml -index 1c0a2ece552..1dd8b2462d4 100644 ---- a/lib/ldb/man/ldb.3.xml -+++ b/lib/ldb/man/ldb.3.xml -@@ -247,7 +247,7 @@ ldb_search(3) manual pages. - Author - - -- ldb was written by -+ ldb was written by - Andrew Tridgell. - - --- -2.46.1 - - -From ba9918d45820fbdb864b5a1e058136eeb0cf1ce7 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Wed, 25 Sep 2024 09:22:08 +0200 -Subject: [PATCH 4/4] lib:ldb: Document environment variables in ldb manpage - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15643 - -Signed-off-by: Andreas Schneider -Reviewed-by: Stefan Metzmacher - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Fri Sep 27 09:06:43 UTC 2024 on atb-devel-224 - -(cherry picked from commit 20a3a94e06a2294206ec233ccc7f873d6ef2aca0) ---- - lib/ldb/man/ldb.3.xml | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/lib/ldb/man/ldb.3.xml b/lib/ldb/man/ldb.3.xml -index 1dd8b2462d4..f8d3cb50446 100644 ---- a/lib/ldb/man/ldb.3.xml -+++ b/lib/ldb/man/ldb.3.xml -@@ -243,6 +243,27 @@ ldb_search(3) manual pages. - - - -+ -+ ENVIRONMENT VARIABLES -+ -+ -+ -+ LDB_URL -+ - connect to the provided URL (cmdline tools only) -+ -+ -+ -+ LDB_MODULES_PATH -+ - path where to load ldb modules from -+ -+ -+ -+ LDB_MODULES_ENABLE_DEEPBIND -+ - enable RTLD_DEEPBIND when loading ldb modules -+ -+ -+ -+ - - Author - --- -2.46.1 - diff --git a/samba-4.21.0-backport-freeipa-support.patch b/samba-4.21.0-backport-freeipa-support.patch deleted file mode 100644 index d1c5776..0000000 --- a/samba-4.21.0-backport-freeipa-support.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 26797d7bd2662718b3eb795f1b8e6100d51e3ab7 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 3 Sep 2024 08:48:24 +0300 -Subject: [PATCH] sync machine password to keytab: handle FreeIPA use case -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -FreeIPA uses own procedure to retrieve keytabs and during the setup of -Samba on FreeIPA client the keytab is already present, only machine -account needs to be set in the secrets database. - -'sync machine password to keytab' option handling broke this use case by -always attempting to contact a domain controller and failing to do so -(Fedora bug https://bugzilla.redhat.com/show_bug.cgi?id=2309199). - -The original synchronizing machine account password to keytab feature -did not have a mechanism to disable its logic at all. - -Signed-off-by: Alexander Bokovoy -Reviewed-by: Pavel Filipenský - -Autobuild-User(master): Alexander Bokovoy -Autobuild-Date(master): Fri Sep 13 13:16:09 UTC 2024 on atb-devel-224 - -(cherry picked from commit 4f577c7b6894132be4842944f2f950b087312b16) ---- - .../security/syncmachinepasswordtokeytab.xml | 29 +++++++++++++++++-- - source3/libads/kerberos_keytab.c | 5 ++++ - source3/utils/net.c | 8 +++++ - source3/utils/testparm.c | 3 +- - 4 files changed, 41 insertions(+), 4 deletions(-) - -diff --git a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -index 4cad9da73f2..f7dc30023d4 100644 ---- a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -+++ b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -@@ -18,7 +18,11 @@ or by winbindd doing regular updates (see -+If no value is present and is different from -+'secrets only', the behavior differs between winbind and net utility: -+ -+ -+ -+ winbind uses value -+ /path/to/keytab:sync_spns:sync_kvno:machine_password -+ where the path to the keytab is obtained either from the krb5 library or from -+ . -+ -+ -+ -+ net changesecretpw -f command uses the default 'disabled' value. -+ -+ No other net subcommands use the 'disabled' value. -+ -+ -+ -+If a single value 'disabled' is present, the synchronization process is -+disabled. This is required for FreeIPA domain member setup where keytab -+synchronization uses a protocol not implemented by Samba. - - - -diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c -index 6ede567b75f..dbf8af44c1f 100644 ---- a/source3/libads/kerberos_keytab.c -+++ b/source3/libads/kerberos_keytab.c -@@ -904,6 +904,11 @@ NTSTATUS sync_pw2keytabs(void) - goto params_ready; - } - -+ if ((*lp_ptr != NULL) && strequal_m(*lp_ptr, "disabled")) { -+ DBG_DEBUG("'sync machine password to keytab' is explicitly disabled.\n"); -+ return NT_STATUS_OK; -+ } -+ - line = lp_ptr; - while (*line) { - DBG_DEBUG("Scanning line: %s\n", *line); -diff --git a/source3/utils/net.c b/source3/utils/net.c -index 7b40d2bee95..c432ebe991f 100644 ---- a/source3/utils/net.c -+++ b/source3/utils/net.c -@@ -207,6 +207,14 @@ static int net_changesecretpw(struct net_context *c, int argc, - struct timeval tv = timeval_current(); - NTTIME now = timeval_to_nttime(&tv); - -+#ifdef HAVE_ADS -+ if (USE_KERBEROS_KEYTAB) { -+ if (lp_sync_machine_password_to_keytab() == NULL) { -+ lp_do_parameter(-1, "sync machine password to keytab", "disabled"); -+ } -+ } -+#endif -+ - if (c->opt_stdin) { - set_line_buffering(stdin); - set_line_buffering(stdout); -diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c -index e3ed336a79a..a31a7a8a30a 100644 ---- a/source3/utils/testparm.c -+++ b/source3/utils/testparm.c -@@ -803,7 +803,8 @@ static int do_global_checks(void) - "instead of 'kerberos method'.\n\n"); - } - -- if (lp_ptr != NULL) { -+ if (lp_ptr != NULL && -+ ((*lp_ptr != NULL) && !strequal_m(*lp_ptr, "disabled"))) { - while (*lp_ptr) { - ret |= pw2kt_check_line(*lp_ptr++); - } --- -2.46.0 - diff --git a/samba-4.21.0-ldb-lmdb.patch b/samba-4.21.0-ldb-lmdb.patch deleted file mode 100644 index 894014a..0000000 --- a/samba-4.21.0-ldb-lmdb.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 9f265d6f3b852a9eed9f19147585fe2801507f63 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Tue, 24 Sep 2024 15:48:23 +0200 -Subject: [PATCH] ldb: Build lmdb backend also in non-AD case - -We should build with lmdb support also if it is not in AD case. The lmdb -backend is also used e.g. by sssd. - -If you don't want to build it, you can always specify --without-ldb-lmdb - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15721 - -Signed-off-by: Andreas Schneider ---- - lib/ldb/wscript | 22 +++++++++------------- - 1 file changed, 9 insertions(+), 13 deletions(-) - -diff --git a/lib/ldb/wscript b/lib/ldb/wscript -index 87aa3bb6d77..f234fa79c10 100644 ---- a/lib/ldb/wscript -+++ b/lib/ldb/wscript -@@ -33,21 +33,17 @@ def configure(conf): - conf.CONFIG_GET('ENABLE_SELFTEST'): - Logs.warn("NOTE: Some AD DC parts of selftest will fail") - -+ conf.env.REQUIRE_LMDB = False -+ elif Options.options.without_ldb_lmdb: -+ if not Options.options.without_ad_dc and \ -+ conf.CONFIG_GET('ENABLE_SELFTEST'): -+ raise Errors.WafError('--without-ldb-lmdb conflicts ' -+ 'with --enable-selftest while ' -+ 'building the AD DC') -+ - conf.env.REQUIRE_LMDB = False - else: -- if Options.options.without_ad_dc: -- conf.env.REQUIRE_LMDB = False -- else: -- if Options.options.without_ldb_lmdb: -- if not Options.options.without_ad_dc and \ -- conf.CONFIG_GET('ENABLE_SELFTEST'): -- raise Errors.WafError('--without-ldb-lmdb conflicts ' -- 'with --enable-selftest while ' -- 'building the AD DC') -- -- conf.env.REQUIRE_LMDB = False -- else: -- conf.env.REQUIRE_LMDB = True -+ conf.env.REQUIRE_LMDB = True - - # if lmdb support is enabled then we require lmdb - # is present, build the mdb back end and enable lmdb support in --- -GitLab - diff --git a/samba-4.21.0-s3-notifyd.patch b/samba-4.21.0-s3-notifyd.patch new file mode 100644 index 0000000..31463fd --- /dev/null +++ b/samba-4.21.0-s3-notifyd.patch @@ -0,0 +1,513 @@ +From c9a7bc3e8f36cb9d6746e23ea56f9c27b82dcf49 Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 22 Jul 2024 12:26:55 +0200 +Subject: [PATCH] s3:notifyd: Use a watcher per db record +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This fixes a O(n²) performance regression in notifyd. The problem was +that we had a watcher per notify instance. This changes the code to have +a watcher per notify db entry. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=14430 + +Signed-off-by: Andreas Schneider +Reviewed-by: Stefan Metzmacher +(cherry picked from commit af011b987a4ad0d3753d83cc0b8d97ad64ba874a) +--- + source3/smbd/notifyd/notifyd.c | 214 ++++++++++++++++++------- + source3/smbd/notifyd/notifyd_db.c | 5 +- + source3/smbd/notifyd/notifyd_entry.c | 51 ++++-- + source3/smbd/notifyd/notifyd_private.h | 46 ++++-- + 4 files changed, 228 insertions(+), 88 deletions(-) + +diff --git a/source3/smbd/notifyd/notifyd.c b/source3/smbd/notifyd/notifyd.c +index 64dd26a7e11..0b07ab3e435 100644 +--- a/source3/smbd/notifyd/notifyd.c ++++ b/source3/smbd/notifyd/notifyd.c +@@ -337,6 +337,7 @@ static bool notifyd_apply_rec_change( + struct messaging_context *msg_ctx) + { + struct db_record *rec = NULL; ++ struct notifyd_watcher watcher = {}; + struct notifyd_instance *instances = NULL; + size_t num_instances; + size_t i; +@@ -344,6 +345,7 @@ static bool notifyd_apply_rec_change( + TDB_DATA value; + NTSTATUS status; + bool ok = false; ++ bool new_watcher = false; + + if (pathlen == 0) { + DBG_WARNING("pathlen==0\n"); +@@ -374,8 +376,12 @@ static bool notifyd_apply_rec_change( + value = dbwrap_record_get_value(rec); + + if (value.dsize != 0) { +- if (!notifyd_parse_entry(value.dptr, value.dsize, NULL, +- &num_instances)) { ++ ok = notifyd_parse_entry(value.dptr, ++ value.dsize, ++ &watcher, ++ NULL, ++ &num_instances); ++ if (!ok) { + goto fail; + } + } +@@ -390,8 +396,22 @@ static bool notifyd_apply_rec_change( + goto fail; + } + +- if (value.dsize != 0) { +- memcpy(instances, value.dptr, value.dsize); ++ if (num_instances > 0) { ++ struct notifyd_instance *tmp = NULL; ++ size_t num_tmp = 0; ++ ++ ok = notifyd_parse_entry(value.dptr, ++ value.dsize, ++ NULL, ++ &tmp, ++ &num_tmp); ++ if (!ok) { ++ goto fail; ++ } ++ ++ memcpy(instances, ++ tmp, ++ sizeof(struct notifyd_instance) * num_tmp); + } + + for (i=0; ifilter, +- .internal_subdir_filter = chg->subdir_filter + }; + + num_instances += 1; + } + +- if ((instance->instance.filter != 0) || +- (instance->instance.subdir_filter != 0)) { +- int ret; ++ /* ++ * Calculate an intersection of the instances filters for the watcher. ++ */ ++ if (instance->instance.filter > 0) { ++ uint32_t filter = instance->instance.filter; ++ ++ if ((watcher.filter & filter) != filter) { ++ watcher.filter |= filter; ++ ++ new_watcher = true; ++ } ++ } ++ ++ /* ++ * Calculate an intersection of the instances subdir_filters for the ++ * watcher. ++ */ ++ if (instance->instance.subdir_filter > 0) { ++ uint32_t subdir_filter = instance->instance.subdir_filter; + +- TALLOC_FREE(instance->sys_watch); ++ if ((watcher.subdir_filter & subdir_filter) != subdir_filter) { ++ watcher.subdir_filter |= subdir_filter; + +- ret = sys_notify_watch(entries, sys_notify_ctx, path, +- &instance->internal_filter, +- &instance->internal_subdir_filter, +- notifyd_sys_callback, msg_ctx, +- &instance->sys_watch); +- if (ret != 0) { +- DBG_WARNING("sys_notify_watch for [%s] returned %s\n", +- path, strerror(errno)); ++ new_watcher = true; + } + } + + if ((instance->instance.filter == 0) && + (instance->instance.subdir_filter == 0)) { ++ uint32_t tmp_filter = 0; ++ uint32_t tmp_subdir_filter = 0; ++ + /* This is a delete request */ +- TALLOC_FREE(instance->sys_watch); + *instance = instances[num_instances-1]; + num_instances -= 1; ++ ++ for (i = 0; i < num_instances; i++) { ++ struct notifyd_instance *tmp = &instances[i]; ++ ++ tmp_filter |= tmp->instance.filter; ++ tmp_subdir_filter |= tmp->instance.subdir_filter; ++ } ++ ++ /* ++ * If the filter has changed, register a new watcher with the ++ * changed filter. ++ */ ++ if (watcher.filter != tmp_filter || ++ watcher.subdir_filter != tmp_subdir_filter) ++ { ++ watcher.filter = tmp_filter; ++ watcher.subdir_filter = tmp_subdir_filter; ++ ++ new_watcher = true; ++ } ++ } ++ ++ if (new_watcher) { ++ /* ++ * In case we removed all notify instances, we want to remove ++ * the watcher. We won't register a new one, if no filters are ++ * set anymore. ++ */ ++ ++ TALLOC_FREE(watcher.sys_watch); ++ ++ watcher.sys_filter = watcher.filter; ++ watcher.sys_subdir_filter = watcher.subdir_filter; ++ ++ /* ++ * Only register a watcher if we have filter. ++ */ ++ if (watcher.filter != 0 || watcher.subdir_filter != 0) { ++ int ret = sys_notify_watch(entries, ++ sys_notify_ctx, ++ path, ++ &watcher.sys_filter, ++ &watcher.sys_subdir_filter, ++ notifyd_sys_callback, ++ msg_ctx, ++ &watcher.sys_watch); ++ if (ret != 0) { ++ DBG_WARNING("sys_notify_watch for [%s] " ++ "returned %s\n", ++ path, ++ strerror(errno)); ++ } ++ } + } + + DBG_DEBUG("%s has %zu instances\n", path, num_instances); + + if (num_instances == 0) { ++ TALLOC_FREE(watcher.sys_watch); ++ + status = dbwrap_record_delete(rec); + if (!NT_STATUS_IS_OK(status)) { + DBG_WARNING("dbwrap_record_delete returned %s\n", +@@ -456,13 +541,21 @@ static bool notifyd_apply_rec_change( + goto fail; + } + } else { +- value = make_tdb_data( +- (uint8_t *)instances, +- sizeof(struct notifyd_instance) * num_instances); ++ struct TDB_DATA iov[2] = { ++ { ++ .dptr = (uint8_t *)&watcher, ++ .dsize = sizeof(struct notifyd_watcher), ++ }, ++ { ++ .dptr = (uint8_t *)instances, ++ .dsize = sizeof(struct notifyd_instance) * ++ num_instances, ++ }, ++ }; + +- status = dbwrap_record_store(rec, value, 0); ++ status = dbwrap_record_storev(rec, iov, ARRAY_SIZE(iov), 0); + if (!NT_STATUS_IS_OK(status)) { +- DBG_WARNING("dbwrap_record_store returned %s\n", ++ DBG_WARNING("dbwrap_record_storev returned %s\n", + nt_errstr(status)); + goto fail; + } +@@ -706,12 +799,18 @@ static void notifyd_trigger_parser(TDB_DATA key, TDB_DATA data, + .when = tstate->msg->when }; + struct iovec iov[2]; + size_t path_len = key.dsize; ++ struct notifyd_watcher watcher = {}; + struct notifyd_instance *instances = NULL; + size_t num_instances = 0; + size_t i; ++ bool ok; + +- if (!notifyd_parse_entry(data.dptr, data.dsize, &instances, +- &num_instances)) { ++ ok = notifyd_parse_entry(data.dptr, ++ data.dsize, ++ &watcher, ++ &instances, ++ &num_instances); ++ if (!ok) { + DBG_DEBUG("Could not parse notifyd_entry\n"); + return; + } +@@ -734,9 +833,11 @@ static void notifyd_trigger_parser(TDB_DATA key, TDB_DATA data, + + if (tstate->covered_by_sys_notify) { + if (tstate->recursive) { +- i_filter = instance->internal_subdir_filter; ++ i_filter = watcher.sys_subdir_filter & ++ instance->instance.subdir_filter; + } else { +- i_filter = instance->internal_filter; ++ i_filter = watcher.sys_filter & ++ instance->instance.filter; + } + } else { + if (tstate->recursive) { +@@ -1146,46 +1247,39 @@ static int notifyd_add_proxy_syswatches(struct db_record *rec, + struct db_context *db = dbwrap_record_get_db(rec); + TDB_DATA key = dbwrap_record_get_key(rec); + TDB_DATA value = dbwrap_record_get_value(rec); +- struct notifyd_instance *instances = NULL; +- size_t num_instances = 0; +- size_t i; ++ struct notifyd_watcher watcher = {}; + char path[key.dsize+1]; + bool ok; ++ int ret; + + memcpy(path, key.dptr, key.dsize); + path[key.dsize] = '\0'; + +- ok = notifyd_parse_entry(value.dptr, value.dsize, &instances, +- &num_instances); ++ /* This is a remote database, we just need the watcher. */ ++ ok = notifyd_parse_entry(value.dptr, value.dsize, &watcher, NULL, NULL); + if (!ok) { + DBG_WARNING("Could not parse notifyd entry for %s\n", path); + return 0; + } + +- for (i=0; iinstance.filter; +- uint32_t subdir_filter = instance->instance.subdir_filter; +- int ret; ++ watcher.sys_watch = NULL; ++ watcher.sys_filter = watcher.filter; ++ watcher.sys_subdir_filter = watcher.subdir_filter; + +- /* +- * This is a remote database. Pointers that we were +- * given don't make sense locally. Initialize to NULL +- * in case sys_notify_watch fails. +- */ +- instances[i].sys_watch = NULL; +- +- ret = state->sys_notify_watch( +- db, state->sys_notify_ctx, path, +- &filter, &subdir_filter, +- notifyd_sys_callback, state->msg_ctx, +- &instance->sys_watch); +- if (ret != 0) { +- DBG_WARNING("inotify_watch returned %s\n", +- strerror(errno)); +- } ++ ret = state->sys_notify_watch(db, ++ state->sys_notify_ctx, ++ path, ++ &watcher.filter, ++ &watcher.subdir_filter, ++ notifyd_sys_callback, ++ state->msg_ctx, ++ &watcher.sys_watch); ++ if (ret != 0) { ++ DBG_WARNING("inotify_watch returned %s\n", strerror(errno)); + } + ++ memcpy(value.dptr, &watcher, sizeof(struct notifyd_watcher)); ++ + return 0; + } + +@@ -1193,21 +1287,17 @@ static int notifyd_db_del_syswatches(struct db_record *rec, void *private_data) + { + TDB_DATA key = dbwrap_record_get_key(rec); + TDB_DATA value = dbwrap_record_get_value(rec); +- struct notifyd_instance *instances = NULL; +- size_t num_instances = 0; +- size_t i; ++ struct notifyd_watcher watcher = {}; + bool ok; + +- ok = notifyd_parse_entry(value.dptr, value.dsize, &instances, +- &num_instances); ++ ok = notifyd_parse_entry(value.dptr, value.dsize, &watcher, NULL, NULL); + if (!ok) { + DBG_WARNING("Could not parse notifyd entry for %.*s\n", + (int)key.dsize, (char *)key.dptr); + return 0; + } +- for (i=0; ientries database + */ + +-bool notifyd_parse_entry( +- uint8_t *buf, +- size_t buflen, +- struct notifyd_instance **instances, +- size_t *num_instances) ++/** ++ * @brief Parse a notifyd database entry. ++ * ++ * The memory we pass down needs to be aligned. If it isn't aligned we can run ++ * into obscure errors as we just point into the data buffer. ++ * ++ * @param data The data to parse ++ * @param data_len The length of the data to parse ++ * @param watcher A pointer to store the watcher data or NULL. ++ * @param instances A pointer to store the array of notify instances or NULL. ++ * @param pnum_instances The number of elements in the array. If you just want ++ * the number of elements pass NULL for the watcher and instances pointers. ++ * ++ * @return true on success, false if an error occurred. ++ */ ++bool notifyd_parse_entry(uint8_t *data, ++ size_t data_len, ++ struct notifyd_watcher *watcher, ++ struct notifyd_instance **instances, ++ size_t *pnum_instances) + { +- if ((buflen % sizeof(struct notifyd_instance)) != 0) { +- DBG_WARNING("invalid buffer size: %zu\n", buflen); ++ size_t ilen; ++ ++ if (data_len < sizeof(struct notifyd_watcher)) { + return false; + } + +- if (instances != NULL) { +- *instances = (struct notifyd_instance *)buf; ++ if (watcher != NULL) { ++ *watcher = *((struct notifyd_watcher *)(uintptr_t)data); + } +- if (num_instances != NULL) { +- *num_instances = buflen / sizeof(struct notifyd_instance); ++ ++ ilen = data_len - sizeof(struct notifyd_watcher); ++ if ((ilen % sizeof(struct notifyd_instance)) != 0) { ++ return false; ++ } ++ ++ if (pnum_instances != NULL) { ++ *pnum_instances = ilen / sizeof(struct notifyd_instance); + } ++ if (instances != NULL) { ++ /* The (uintptr_t) cast removes a warning from -Wcast-align. */ ++ *instances = ++ (struct notifyd_instance *)(uintptr_t) ++ (data + sizeof(struct notifyd_watcher)); ++ } ++ + return true; + } +diff --git a/source3/smbd/notifyd/notifyd_private.h b/source3/smbd/notifyd/notifyd_private.h +index 36c08f47c54..db8e6e1c005 100644 +--- a/source3/smbd/notifyd/notifyd_private.h ++++ b/source3/smbd/notifyd/notifyd_private.h +@@ -20,30 +20,48 @@ + #include "lib/util/server_id.h" + #include "notifyd.h" + ++ + /* +- * notifyd's representation of a notify instance ++ * Representation of a watcher for a path ++ * ++ * This will be stored in the db. + */ +-struct notifyd_instance { +- struct server_id client; +- struct notify_instance instance; +- +- void *sys_watch; /* inotify/fam/etc handle */ ++struct notifyd_watcher { ++ /* ++ * This is an intersections of the filter the watcher is listening for. ++ */ ++ uint32_t filter; ++ uint32_t subdir_filter; + + /* +- * Filters after sys_watch took responsibility of some bits ++ * Those are inout variables passed to the sys_watcher. The sys_watcher ++ * will remove the bits it can't handle. + */ +- uint32_t internal_filter; +- uint32_t internal_subdir_filter; ++ uint32_t sys_filter; ++ uint32_t sys_subdir_filter; ++ ++ /* The handle for inotify/fam etc. */ ++ void *sys_watch; ++}; ++ ++/* ++ * Representation of a notifyd instance ++ * ++ * This will be stored in the db. ++ */ ++struct notifyd_instance { ++ struct server_id client; ++ struct notify_instance instance; + }; + + /* + * Parse an entry in the notifyd_context->entries database + */ + +-bool notifyd_parse_entry( +- uint8_t *buf, +- size_t buflen, +- struct notifyd_instance **instances, +- size_t *num_instances); ++bool notifyd_parse_entry(uint8_t *data, ++ size_t data_len, ++ struct notifyd_watcher *watcher, ++ struct notifyd_instance **instances, ++ size_t *num_instances); + + #endif +-- +2.46.1 + diff --git a/samba.spec b/samba.spec index 67e3895..0de5d76 100644 --- a/samba.spec +++ b/samba.spec @@ -150,7 +150,7 @@ %define samba_requires_eq() %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} = %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") -%global samba_version 4.21.0 +%global samba_version 4.21.1 # The release field is extended: # [.][.]%%{?dist}[.] @@ -252,10 +252,7 @@ Source18: samba-winbind-systemd-sysusers.conf Source201: README.downgrade Source202: samba.abignore -Patch0: samba-4.21.0-backport-freeipa-support.patch -# https://gitlab.com/samba-team/samba/-/merge_requests/3807 -Patch1: samba-4.21.0-ldb-lmdb.patch -Patch2: samba-4-21-fix-libldb-deepbind.patch +Patch0: samba-4.21.0-s3-notifyd.patch Requires(pre): %{name}-common = %{samba_depver} Requires: %{name}-common = %{samba_depver} diff --git a/sources b/sources index 3e8e284..a1c1a28 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (samba-4.21.0.tar.xz) = d05c823afc04669766130745c139e7d129eb9961525453d6da8b5ee6693d4c08192496d07e5c211e86d553956504fb9df16611cc9268111b71b95c7f2fa868a0 -SHA512 (samba-4.21.0.tar.asc) = 7fffbd0b88b42dd7f340e4bcae17da4a68a0f8de86a1e71534a4a02a477a746e4cdb16df7c0da33aaf13278cefb452bd9b7c61ed029e248576f7158e8bec339e +SHA512 (samba-4.21.1.tar.xz) = 182759820708c9df26fbcb09e755e81236ecacf543f3e18a05dbd0ea551ab072d338fe239eb99ff506f158ec45e981a893ce46eacdde6e073ee85ceb43e2669a +SHA512 (samba-4.21.1.tar.asc) = 2c1e4b347044e15a852ced8bb412a3f372fd2c2b5e0001b1a773f7283f2d8fa62942143b46cbc3f16b18882255cf0aac4426002453971361b0002357657484f1