From 172ab33b8f8fe6b23b7a70c9a14a2003cee49c36 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 11 Nov 2025 15:46:40 +0000 Subject: [PATCH] import UBI samba-4.22.4-6.el9_7 --- .gitignore | 2 +- .samba.metadata | 2 +- SOURCES/redhat-4.21.patch | 8133 ---------------------------------- SOURCES/redhat-4.22.patch | 492 ++ SOURCES/samba-4.21.3.tar.asc | 16 - SOURCES/samba-4.22.4.tar.asc | 16 + SOURCES/samba.logrotate | 2 +- SPECS/samba.spec | 271 +- 8 files changed, 641 insertions(+), 8293 deletions(-) delete mode 100644 SOURCES/redhat-4.21.patch create mode 100644 SOURCES/redhat-4.22.patch delete mode 100644 SOURCES/samba-4.21.3.tar.asc create mode 100644 SOURCES/samba-4.22.4.tar.asc diff --git a/.gitignore b/.gitignore index 6bc5d98..8a9f3b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/samba-4.21.3.tar.xz +SOURCES/samba-4.22.4.tar.xz SOURCES/samba-pubkey_AA99442FB680B620.gpg diff --git a/.samba.metadata b/.samba.metadata index 07e804b..8bd141f 100644 --- a/.samba.metadata +++ b/.samba.metadata @@ -1,2 +1,2 @@ -c3c2f51037818ee9e1d24b5b9add13d5f86fdb01 SOURCES/samba-4.21.3.tar.xz +1437538612045e08c3dde1527825d11a11a6d71f SOURCES/samba-4.22.4.tar.xz 971f563c447eda8d144d6c9e743cd0f0488c0d9e SOURCES/samba-pubkey_AA99442FB680B620.gpg diff --git a/SOURCES/redhat-4.21.patch b/SOURCES/redhat-4.21.patch deleted file mode 100644 index 4cf4b56..0000000 --- a/SOURCES/redhat-4.21.patch +++ /dev/null @@ -1,8133 +0,0 @@ -From 9032322cc713e82a316b271bb2fa0a867c69b021 Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 22 Jul 2024 12:26:55 +0200 -Subject: [PATCH 01/43] 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.51.0 - - -From da6309049eb21ec5cd6bdf7942203960adbc37c0 Mon Sep 17 00:00:00 2001 -From: Douglas Bagnall -Date: Thu, 5 Dec 2024 16:35:51 +1300 -Subject: [PATCH 02/43] util: add a crypt wrapper, derived from - dsdb:password_hash - -This is going to be used by the dsdb password_hash module, and exposed -to Python via pyglue. - -We're doing this because Python 3.13 has dropped crypt from the Python -standard library. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15756 - -Reviewed-by: Andreas Schneider -(cherry picked from commit 93bc860e8f344a96d0496edbc5d463f2c5411fcd) ---- - lib/util/util_crypt.c | 90 ++++++++++++++++++++++++++++++++++++++++++ - lib/util/util_crypt.h | 5 +++ - lib/util/wscript_build | 6 +++ - 3 files changed, 101 insertions(+) - create mode 100644 lib/util/util_crypt.c - create mode 100644 lib/util/util_crypt.h - -diff --git a/lib/util/util_crypt.c b/lib/util/util_crypt.c -new file mode 100644 -index 00000000000..0f7b2d0fd31 ---- /dev/null -+++ b/lib/util/util_crypt.c -@@ -0,0 +1,90 @@ -+#include -+#include "data_blob.h" -+#include -+#include -+#include "util_crypt.h" -+ -+ -+static int crypt_as_best_we_can(const char *phrase, -+ const char *setting, -+ const char **hashp) -+{ -+ int ret = 0; -+ const char *hash = NULL; -+ -+#if defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT_RN) -+ struct crypt_data crypt_data = { -+ .initialized = 0 /* working storage used by crypt */ -+ }; -+#endif -+ -+ /* -+ * crypt_r() and crypt() may return a null pointer upon error -+ * depending on how libcrypt was configured, so we prefer -+ * crypt_rn() from libcrypt / libxcrypt which always returns -+ * NULL on error. -+ * -+ * POSIX specifies returning a null pointer and setting -+ * errno. -+ * -+ * RHEL 7 (which does not use libcrypt / libxcrypt) returns a -+ * non-NULL pointer from crypt_r() on success but (always?) -+ * sets errno during internal processing in the NSS crypto -+ * subsystem. -+ * -+ * By preferring crypt_rn we avoid the 'return non-NULL but -+ * set-errno' that we otherwise cannot tell apart from the -+ * RHEL 7 behaviour. -+ */ -+ errno = 0; -+ -+#ifdef HAVE_CRYPT_RN -+ hash = crypt_rn(phrase, setting, -+ &crypt_data, -+ sizeof(crypt_data)); -+#elif HAVE_CRYPT_R -+ hash = crypt_r(phrase, setting, &crypt_data); -+#else -+ /* -+ * No crypt_r falling back to crypt, which is NOT thread safe -+ * Thread safety MT-Unsafe race:crypt -+ */ -+ hash = crypt(phrase, setting); -+#endif -+ /* -+ * On error, crypt() and crypt_r() may return a null pointer, -+ * or a pointer to an invalid hash beginning with a '*'. -+ */ -+ ret = errno; -+ errno = 0; -+ if (hash == NULL || hash[0] == '*') { -+ if (ret == 0) { -+ /* this is annoying */ -+ ret = ENOTRECOVERABLE; -+ } -+ } -+ -+ *hashp = hash; -+ return ret; -+} -+ -+ -+int talloc_crypt_blob(TALLOC_CTX *mem_ctx, -+ const char *phrase, -+ const char *setting, -+ DATA_BLOB *blob) -+{ -+ const char *hash = NULL; -+ int ret = crypt_as_best_we_can(phrase, setting, &hash); -+ if (ret != 0) { -+ blob->data = NULL; -+ blob->length = 0; -+ return ret; -+ } -+ blob->length = strlen(hash); -+ blob->data = talloc_memdup(mem_ctx, hash, blob->length); -+ if (blob->data == NULL) { -+ return ENOMEM; -+ } -+ return 0; -+} -diff --git a/lib/util/util_crypt.h b/lib/util/util_crypt.h -new file mode 100644 -index 00000000000..8c289e489e8 ---- /dev/null -+++ b/lib/util/util_crypt.h -@@ -0,0 +1,5 @@ -+ -+int talloc_crypt_blob(TALLOC_CTX *mem_ctx, -+ const char *phrase, -+ const char *cmd, -+ DATA_BLOB *blob); -diff --git a/lib/util/wscript_build b/lib/util/wscript_build -index b4fcfeaba07..7de9c0b7b17 100644 ---- a/lib/util/wscript_build -+++ b/lib/util/wscript_build -@@ -253,6 +253,12 @@ else: - private_library=True, - local_include=False) - -+ bld.SAMBA_LIBRARY('util_crypt', -+ source='util_crypt.c', -+ deps='talloc crypt', -+ private_library=True, -+ local_include=False) -+ - - bld.SAMBA_SUBSYSTEM('UNIX_PRIVS', - source='unix_privs.c', --- -2.51.0 - - -From 334093563640f232bb337675417f1e8a410987de Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Mon, 20 Jan 2025 16:00:51 +0100 -Subject: [PATCH 03/43] s3: Add new keytab specifiers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15759 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 15e191736d3eaba83b2fb4b901e1df2214526b64) ---- - selftest/target/Samba3.pm | 3 +- - source3/libads/kerberos_keytab.c | 631 +++++++++++++-------- - source3/script/tests/test_update_keytab.sh | 449 +++++++++++---- - 3 files changed, 730 insertions(+), 353 deletions(-) - -diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm -index 17343e63e52..cc4498ff36e 100755 ---- a/selftest/target/Samba3.pm -+++ b/selftest/target/Samba3.pm -@@ -807,7 +807,8 @@ sub provision_ad_member - \"$prefix_abs/keytab2:spn_prefixes=imap,smtp:additional_dns_hostnames:netbios_aliases:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab2k:spn_prefixes=imap,smtp:additional_dns_hostnames:sync_kvno:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab3:spns=wurst/brot\@$dcvars->{REALM}:machine_password:sync_etypes\", \\ -- \"$prefix_abs/keytab3k:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\" -+ \"$prefix_abs/keytab3k:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\", \\ -+ \"$prefix_abs/keytab4k:account_name:sync_account_name:spn_prefixes=imap,smtp:additional_dns_hostnames:netbios_aliases:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\" - "; - } - -diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c -index dbf8af44c1f..619a7bda0d4 100644 ---- a/source3/libads/kerberos_keytab.c -+++ b/source3/libads/kerberos_keytab.c -@@ -30,6 +30,7 @@ - #include "ads.h" - #include "secrets.h" - #include "librpc/gen_ndr/ndr_secrets.h" -+#include "lib/util/string_wrappers.h" - - #ifdef HAVE_KRB5 - -@@ -41,44 +42,59 @@ - #endif - - enum spn_spec_type { -- SPN_SPEC_DEFAULT, -- SPN_SPEC_SYNC, -+ SPN_SPEC_ACCOUNT_NAME, -+ SPN_SPEC_SYNC_ACCOUNT_NAME, -+ SPN_SPEC_HOST, -+ SPN_SPEC_SYNC_UPN, -+ SPN_SPEC_SYNC_SPNS, - SPN_SPEC_FULL, -- SPN_SPEC_PREFIX -+ SPN_SPEC_PREFIX, -+ SPN_SPEC_MAX - }; - --/* pw2kt_conf contains 1 parsed line from "sync machine password to keytab" */ --struct pw2kt_conf { -- enum spn_spec_type spn_spec; -+/* Specifier */ -+struct pw2kt_specifier { -+ bool is_set; -+ char **spn_spec_vals; /* Array of full SPNs or prefixes */ -+}; -+ -+/* Descriptor contains 1 parsed line from "sync machine password to keytab" */ -+struct pw2kt_keytab_desc { - char *keytab; - bool sync_etypes; - bool sync_kvno; - bool additional_dns_hostnames; - bool netbios_aliases; - bool machine_password; -- char **spn_spec_array; -- size_t num_spn_spec; -+ struct pw2kt_specifier spec_array[SPN_SPEC_MAX]; - }; - --/* State used by pw2kt */ --struct pw2kt_state { -+/* Global state - stores initial data */ -+struct pw2kt_global_state { - /* Array of parsed lines from "sync machine password to keytab" */ -- struct pw2kt_conf *keytabs; -- size_t num_keytabs; -+ struct pw2kt_keytab_desc *keytabs; -+ /* Accumulated configuration from all keytabs */ - bool sync_etypes; - bool sync_kvno; - bool sync_spns; -+ bool sync_upn; -+ bool sync_sam_account; - /* These are from DC */ - krb5_kvno ad_kvno; - uint32_t ad_etypes; -+ char *ad_upn; -+ char *ad_sam_account; - char **ad_spn_array; - size_t ad_num_spns; - /* This is from secrets.db */ - struct secrets_domain_info1 *info; - }; - --/* State used by pw2kt_process_keytab */ --struct pw2kt_process_state { -+/* -+ * Manages krb5lib data created during processing of 'global state'. -+ * One instance per keytab. -+ */ -+struct pw2kt_keytab_state { - krb5_keytab keytab; - krb5_context context; - krb5_keytab_entry *array1; -@@ -88,151 +104,206 @@ struct pw2kt_process_state { - krb5_enctype preferred_etype; - }; - --static ADS_STATUS pw2kt_scan_add_spn(TALLOC_CTX *ctx, -- const char *spn, -- struct pw2kt_conf *conf) -+static ADS_STATUS pw2kt_add_val(TALLOC_CTX *ctx, -+ struct pw2kt_specifier *spec, -+ const char *spn_val) - { -- conf->spn_spec_array = talloc_realloc(ctx, -- conf->spn_spec_array, -- char *, -- conf->num_spn_spec + 1); -- if (conf->spn_spec_array == NULL) { -+ size_t len = talloc_array_length(spec->spn_spec_vals); -+ spec->spn_spec_vals = talloc_realloc(ctx, -+ spec->spn_spec_vals, -+ char *, -+ len + 1); -+ if (spec->spn_spec_vals == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- conf->spn_spec_array[conf->num_spn_spec] = talloc_strdup( -- conf->spn_spec_array, spn); -- if (conf->spn_spec_array[conf->num_spn_spec] == NULL) { -+ spec->spn_spec_vals[len] = talloc_strdup(spec->spn_spec_vals, spn_val); -+ if (spec->spn_spec_vals[len] == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- conf->num_spn_spec++; - - return ADS_SUCCESS; - } - -+static ADS_STATUS pw2kt_scan_spec(TALLOC_CTX *ctx, -+ struct pw2kt_global_state *gstate, -+ struct pw2kt_keytab_desc *desc, -+ const char *option) -+{ -+ enum spn_spec_type spec_type; -+ struct pw2kt_specifier *spec; -+ char *vals = NULL; -+ char *tmp = NULL; -+ ADS_STATUS status; -+ -+ /* First check for options sync_kvno, sync_etypes, ... */ -+ if (strequal(option, "sync_kvno")) { -+ desc->sync_kvno = gstate->sync_kvno = true; -+ return ADS_SUCCESS; -+ } else if (strequal(option, "sync_etypes")) { -+ desc->sync_etypes = gstate->sync_etypes = true; -+ return ADS_SUCCESS; -+ } else if (strequal(option, "additional_dns_hostnames")) { -+ desc->additional_dns_hostnames = true; -+ return ADS_SUCCESS; -+ } else if (strequal(option, "netbios_aliases")) { -+ desc->netbios_aliases = true; -+ return ADS_SUCCESS; -+ } else if (strequal(option, "machine_password")) { -+ desc->machine_password = true; -+ return ADS_SUCCESS; -+ } -+ -+ vals = strchr_m(option, '='); -+ if (vals != NULL) { -+ *vals = 0; -+ vals++; -+ } -+ -+ if (strequal(option, "account_name")) { -+ spec_type = SPN_SPEC_ACCOUNT_NAME; -+ } else if (strequal(option, "sync_account_name")) { -+ spec_type = SPN_SPEC_SYNC_ACCOUNT_NAME; -+ gstate->sync_sam_account = true; -+ } else if (strequal(option, "host")) { -+ spec_type = SPN_SPEC_HOST; -+ } else if (strequal(option, "sync_upn")) { -+ spec_type = SPN_SPEC_SYNC_UPN; -+ gstate->sync_upn = true; -+ } else if (strequal(option, "sync_spns")) { -+ spec_type = SPN_SPEC_SYNC_SPNS; -+ gstate->sync_spns = true; -+ } else if (strequal(option, "spns")) { -+ spec_type = SPN_SPEC_FULL; -+ } else if (strequal(option, "spn_prefixes")) { -+ spec_type = SPN_SPEC_PREFIX; -+ } else { -+ DBG_ERR("Invalid option: '%s'\n", option); -+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); -+ } -+ -+ desc->spec_array[spec_type].is_set = true; -+ if (spec_type != SPN_SPEC_PREFIX && spec_type != SPN_SPEC_FULL) { -+ return ADS_SUCCESS; -+ } -+ if (vals == NULL) { -+ DBG_ERR("SPN specifier: %s is missing '='\n", option); -+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); -+ } -+ spec = &desc->spec_array[spec_type]; -+ -+ /* Entries are separated via ',' */ -+ while ((tmp = strchr_m(vals, ',')) != NULL) { -+ *tmp = 0; -+ tmp++; -+ status = pw2kt_add_val(ctx, spec, vals); -+ if (!ADS_ERR_OK(status)) { -+ return status; -+ } -+ vals = tmp; -+ if (*vals == 0) { -+ DBG_ERR("Invalid syntax (trailing ','): %s\n", option); -+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); -+ } -+ } -+ /* Process the last entry */ -+ return pw2kt_add_val(ctx, spec, vals); -+} -+ - /* - * Parse the smb.conf and find out if it is needed to read from DC: -- * - servicePrincipalNames -+ * - servicePrincipalName - * - msDs-KeyVersionNumber -+ * - userPrincipalName -+ * - sAMAccountName -+ * -+ * Example of a line: -+ * /etc/krb5/krb5.keytab:account_name:snps=s1@REALM.COM,spn2@REALM.ORG:host:sync_kvno:machine_password - */ --static ADS_STATUS pw2kt_scan_line(const char *line, struct pw2kt_state *state) -+static ADS_STATUS pw2kt_scan_line(const char *line, -+ struct pw2kt_global_state *gstate) - { -- char *keytabname = NULL; -- char *spn_spec = NULL; -- char *spn_val = NULL; -- char *option = NULL; -- struct pw2kt_conf *conf = NULL; -+ char *tmp = NULL; -+ char *olist = NULL; -+ struct pw2kt_keytab_desc *desc = NULL; - ADS_STATUS status; -+ size_t num_keytabs = talloc_array_length(gstate->keytabs); - -- state->keytabs = talloc_realloc(state, -- state->keytabs, -- struct pw2kt_conf, -- state->num_keytabs + 1); -- if (state->keytabs == NULL) { -+ gstate->keytabs = talloc_realloc(gstate, -+ gstate->keytabs, -+ struct pw2kt_keytab_desc, -+ num_keytabs + 1); -+ if (gstate->keytabs == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- conf = &state->keytabs[state->num_keytabs]; -- state->num_keytabs++; -+ desc = &gstate->keytabs[num_keytabs]; -+ ZERO_STRUCT(*desc); - -- keytabname = talloc_strdup(state->keytabs, line); -- if (keytabname == NULL) { -+ desc->keytab = talloc_strdup(gstate->keytabs, line); -+ if (desc->keytab == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - -- ZERO_STRUCT(*conf); -- conf->keytab = keytabname; -- spn_spec = strchr_m(keytabname, ':'); -- if (spn_spec == NULL) { -- DBG_ERR("Invalid format! ':' expected in '%s'\n", keytabname); -+ olist = strchr_m(desc->keytab, ':'); -+ if (olist == NULL) { -+ DBG_ERR("Invalid format! ':' expected in '%s'\n", line); - return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } -- *spn_spec++ = 0; -- -- /* reverse match with strrchr_m() */ -- while ((option = strrchr_m(spn_spec, ':')) != NULL) { -- *option++ = 0; -- if (strequal(option, "sync_kvno")) { -- conf->sync_kvno = state->sync_kvno = true; -- } else if (strequal(option, "sync_etypes")) { -- conf->sync_etypes = state->sync_etypes = true; -- } else if (strequal(option, "additional_dns_hostnames")) { -- conf->additional_dns_hostnames = true; -- } else if (strequal(option, "netbios_aliases")) { -- conf->netbios_aliases = true; -- } else if (strequal(option, "machine_password")) { -- conf->machine_password = true; -- } else { -- DBG_WARNING("Unknown option '%s'!\n", option); -- return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); -- } -- } -+ *olist = 0; -+ olist++; - -- spn_val = strchr_m(spn_spec, '='); -- if (spn_val != NULL) { -- *spn_val++ = 0; -- } -+ /* Always add 'host' principal */ -+ desc->spec_array[SPN_SPEC_HOST].is_set = true; - -- if (strcmp(spn_spec, "account_name") == 0) { -- conf->spn_spec = SPN_SPEC_DEFAULT; -- } else if (strcmp(spn_spec, "sync_spns") == 0) { -- conf->spn_spec = SPN_SPEC_SYNC; -- state->sync_spns = true; -- } else if (strcmp(spn_spec, "spns") == 0 || -- strcmp(spn_spec, "spn_prefixes") == 0) -- { -- char *spn = NULL, *tmp = NULL; -- -- conf->spn_spec = strcmp(spn_spec, "spns") == 0 -- ? SPN_SPEC_FULL -- : SPN_SPEC_PREFIX; -- conf->num_spn_spec = 0; -- spn = spn_val; -- while ((tmp = strchr_m(spn, ',')) != NULL) { -- *tmp++ = 0; -- status = pw2kt_scan_add_spn(state->keytabs, spn, conf); -- if (!ADS_ERR_OK(status)) { -- return status; -- } -- spn = tmp; -+ /* Entries are separated via ':' */ -+ while ((tmp = strchr_m(olist, ':')) != NULL) { -+ *tmp = 0; -+ tmp++; -+ status = pw2kt_scan_spec(gstate->keytabs, gstate, desc, olist); -+ if (!ADS_ERR_OK(status)) { -+ return status; -+ } -+ olist = tmp; -+ if (*olist == 0) { -+ DBG_ERR("Invalid syntax (trailing ':'): %s\n", line); -+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } -- /* Do not forget the last entry */ -- return pw2kt_scan_add_spn(state->keytabs, spn, conf); -- } else { -- DBG_WARNING("Invalid SPN specifier: %s\n", spn_spec); -- return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } -- -- return ADS_SUCCESS; -+ /* Process the last entry */ -+ return pw2kt_scan_spec(gstate->keytabs, gstate, desc, olist); - } - - /* -- * Fill struct pw2kt_state with defaults if "sync machine password to keytab" -- * is missing in smb.conf -+ * Fill struct pw2kt_global_state with defaults if -+ * "sync machine password to keytab" is missing in smb.conf -+ * Creates 1 keytab with 3 SPN specifiers (sync_spns, account_name, host). - */ --static ADS_STATUS pw2kt_default_cfg(const char *name, struct pw2kt_state *state) -+static ADS_STATUS pw2kt_default_cfg(const char *name, -+ struct pw2kt_global_state *state) - { - char *keytabname = NULL; -- struct pw2kt_conf *conf = NULL; -+ struct pw2kt_keytab_desc *desc = NULL; - - state->keytabs = talloc_zero_array(state->keytabs, -- struct pw2kt_conf, -+ struct pw2kt_keytab_desc, - 1); - if (state->keytabs == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- conf = &state->keytabs[0]; -- state->num_keytabs = 1; -+ desc = &state->keytabs[0]; - - keytabname = talloc_strdup(state->keytabs, name); - if (keytabname == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- -- conf->spn_spec = SPN_SPEC_SYNC; -- conf->keytab = keytabname; -- conf->machine_password = true; -- conf->sync_kvno = state->sync_kvno = true; -+ desc->keytab = keytabname; -+ desc->machine_password = true; -+ desc->sync_kvno = state->sync_kvno = true; - state->sync_spns = true; - -+ desc->spec_array[SPN_SPEC_SYNC_SPNS].is_set = true; -+ desc->spec_array[SPN_SPEC_ACCOUNT_NAME].is_set = true; -+ desc->spec_array[SPN_SPEC_HOST].is_set = true; -+ - return ADS_SUCCESS; - } - -@@ -240,7 +311,7 @@ static ADS_STATUS pw2kt_default_cfg(const char *name, struct pw2kt_state *state) - * For the given principal add to the array entries created from all pw->keys[] - */ - static krb5_error_code pw2kt_process_add_pw( -- struct pw2kt_process_state *state2, -+ struct pw2kt_keytab_state *state2, - krb5_principal princ, - krb5_kvno vno, - struct secrets_domain_info1_password *pw) -@@ -287,11 +358,10 @@ static krb5_error_code pw2kt_process_add_pw( - * For the given principal add to the array entries based on password, - * old_password, older_password and next_change->password. - */ --static krb5_error_code pw2kt_process_add_info( -- struct pw2kt_process_state *state2, -- krb5_kvno kvno, -- const char *princs, -- struct secrets_domain_info1 *info) -+static krb5_error_code pw2kt_process_add_info(struct pw2kt_keytab_state *state2, -+ krb5_kvno kvno, -+ const char *princs, -+ struct secrets_domain_info1 *info) - { - krb5_error_code ret; - krb5_principal princ = NULL; -@@ -336,7 +406,7 @@ static krb5_error_code pw2kt_process_add_info( - return ret; - } - --static int pw2kt_process_state_destructor(struct pw2kt_process_state *state2) -+static int pw2kt_keytab_state_destructor(struct pw2kt_keytab_state *state2) - { - int i; - size_t len2 = talloc_array_length(state2->array2); -@@ -356,7 +426,7 @@ static int pw2kt_process_state_destructor(struct pw2kt_process_state *state2) - } - - /* Read the whole keytab to krb5_keytab_entry array */ --static krb5_error_code pw2kt_process_kt2ar(struct pw2kt_process_state *state2) -+static krb5_error_code pw2kt_process_kt2ar(struct pw2kt_keytab_state *state2) - { - krb5_error_code ret = 0, ret2 = 0; - krb5_kt_cursor cursor; -@@ -402,18 +472,173 @@ static krb5_error_code pw2kt_process_kt2ar(struct pw2kt_process_state *state2) - return ret != 0 ? ret : ret2; - } - --static ADS_STATUS pw2kt_process_keytab(struct pw2kt_state *state, -- struct pw2kt_conf *keytabptr) -+#define ADD_INFO(P) \ -+ ret = pw2kt_process_add_info(state2, kvno, (P), gstate->info); \ -+ if (ret != 0) { \ -+ return ADS_ERROR_KRB5(ret); \ -+ } -+ -+static ADS_STATUS pw2kt_add_prefix(struct pw2kt_global_state *gstate, -+ struct pw2kt_keytab_state *state2, -+ struct pw2kt_keytab_desc *keytabptr, -+ const char *prefix) - { - krb5_error_code ret = 0; -- krb5_kvno kvno = -1; -- size_t i, j, len1 = 0, len2 = 0; -+ krb5_kvno kvno = keytabptr->sync_kvno ? gstate->ad_kvno : -1; - char *princ_s = NULL; - const char **netbios_alias = NULL; - const char **addl_hostnames = NULL; -+ -+ /* Add prefix/dnshostname@REALM */ -+ princ_s = talloc_asprintf(talloc_tos(), -+ "%s/%s@%s", -+ prefix, -+ lp_dns_hostname(), -+ lp_realm()); -+ if (princ_s == NULL) { -+ return ADS_ERROR_KRB5(ENOMEM); -+ } -+ ADD_INFO(princ_s); -+ -+ /* Add prefix/NETBIOSNAME@REALM */ -+ princ_s = talloc_asprintf(talloc_tos(), -+ "%s/%s@%s", -+ prefix, -+ lp_netbios_name(), -+ lp_realm()); -+ if (princ_s == NULL) { -+ return ADS_ERROR_KRB5(ENOMEM); -+ } -+ ADD_INFO(princ_s); -+ -+ if (keytabptr->netbios_aliases) { -+ for (netbios_alias = lp_netbios_aliases(); -+ netbios_alias != NULL && *netbios_alias != NULL; -+ netbios_alias++) -+ { -+ fstring netbios_lower; -+ -+ fstrcpy(netbios_lower, *netbios_alias); -+ if (!strlower_m(netbios_lower)) { -+ return ADS_ERROR_NT( -+ NT_STATUS_INVALID_PARAMETER); -+ } -+ -+ /* Add prefix/NETBIOSALIAS@REALM */ -+ princ_s = talloc_asprintf(talloc_tos(), -+ "%s/%s@%s", -+ prefix, -+ *netbios_alias, -+ lp_realm()); -+ if (princ_s == NULL) { -+ return ADS_ERROR_KRB5(ENOMEM); -+ } -+ ADD_INFO(princ_s); -+ -+ /* Add prefix/netbiosalias.dnsdomain@REALM */ -+ princ_s = talloc_asprintf(talloc_tos(), -+ "%s/%s.%s@%s", -+ prefix, -+ netbios_lower, -+ lp_dnsdomain(), -+ lp_realm()); -+ if (princ_s == NULL) { -+ return ADS_ERROR_KRB5(ENOMEM); -+ } -+ ADD_INFO(princ_s); -+ } -+ } -+ -+ if (keytabptr->additional_dns_hostnames) { -+ for (addl_hostnames = lp_additional_dns_hostnames(); -+ addl_hostnames != NULL && *addl_hostnames != NULL; -+ addl_hostnames++) -+ { -+ /* Add prefix/additionalhostname@REALM */ -+ princ_s = talloc_asprintf(talloc_tos(), -+ "%s/%s@%s", -+ prefix, -+ *addl_hostnames, -+ lp_realm()); -+ if (princ_s == NULL) { -+ return ADS_ERROR_KRB5(ENOMEM); -+ } -+ ADD_INFO(princ_s); -+ } -+ } -+ return ADS_SUCCESS; -+} -+ -+static ADS_STATUS pw2kt_process_specifier(struct pw2kt_global_state *gstate, -+ struct pw2kt_keytab_state *state2, -+ struct pw2kt_keytab_desc *keytabptr, -+ enum spn_spec_type spec_type) -+{ -+ krb5_error_code ret = 0; -+ ADS_STATUS status; -+ krb5_kvno kvno = keytabptr->sync_kvno ? gstate->ad_kvno : -1; -+ struct pw2kt_specifier *spec = &keytabptr->spec_array[spec_type]; -+ size_t i, num_spn_spec_vals; -+ -+ if (!spec->is_set) { -+ return ADS_SUCCESS; -+ } -+ switch (spec_type) { -+ case SPN_SPEC_ACCOUNT_NAME: -+ ADD_INFO(gstate->info->account_name); -+ break; -+ case SPN_SPEC_SYNC_ACCOUNT_NAME: -+ ADD_INFO(gstate->ad_sam_account); -+ break; -+ case SPN_SPEC_HOST: -+ status = pw2kt_add_prefix(gstate, state2, keytabptr, "host"); -+ if (!ADS_ERR_OK(status)) { -+ return status; -+ } -+ break; -+ case SPN_SPEC_SYNC_UPN: -+ if (gstate->ad_upn != NULL) { -+ ADD_INFO(gstate->ad_upn); -+ } -+ break; -+ case SPN_SPEC_SYNC_SPNS: -+ for (i = 0; i < gstate->ad_num_spns; i++) { -+ ADD_INFO(gstate->ad_spn_array[i]); -+ } -+ break; -+ case SPN_SPEC_FULL: -+ num_spn_spec_vals = talloc_array_length(spec->spn_spec_vals); -+ for (i = 0; i < num_spn_spec_vals; i++) { -+ ADD_INFO(spec->spn_spec_vals[i]); -+ } -+ break; -+ case SPN_SPEC_PREFIX: -+ num_spn_spec_vals = talloc_array_length(spec->spn_spec_vals); -+ for (i = 0; i < num_spn_spec_vals; i++) { -+ status = pw2kt_add_prefix(gstate, -+ state2, -+ keytabptr, -+ spec->spn_spec_vals[i]); -+ if (!ADS_ERR_OK(status)) { -+ return status; -+ } -+ } -+ break; -+ default: -+ return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); -+ } -+ return ADS_SUCCESS; -+} -+ -+static ADS_STATUS pw2kt_process_keytab(struct pw2kt_global_state *state, -+ struct pw2kt_keytab_desc *keytabptr) -+{ -+ krb5_error_code ret = 0; -+ size_t i, j, k, len1 = 0, len2 = 0; - size_t *index_array1 = NULL; - size_t *index_array2 = NULL; -- struct pw2kt_process_state *state2 = NULL; -+ struct pw2kt_keytab_state *state2 = NULL; -+ ADS_STATUS status; - - if (!keytabptr->machine_password) { - DBG_ERR("No 'machine_password' option for '%s'. Skip it.\n", -@@ -421,11 +646,11 @@ static ADS_STATUS pw2kt_process_keytab(struct pw2kt_state *state, - return ADS_SUCCESS; - } - -- state2 = talloc_zero(state, struct pw2kt_process_state); -+ state2 = talloc_zero(state, struct pw2kt_keytab_state); - if (state2 == NULL) { - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } -- talloc_set_destructor(state2, pw2kt_process_state_destructor); -+ talloc_set_destructor(state2, pw2kt_keytab_state_destructor); - - ret = smb_krb5_init_context_common(&state2->context); - if (ret != 0) { -@@ -479,100 +704,11 @@ static ADS_STATUS pw2kt_process_keytab(struct pw2kt_state *state, - } - } - -- if (keytabptr->sync_kvno) { -- kvno = state->ad_kvno; -- } -- --#define ADD_INFO(P) \ -- ret = pw2kt_process_add_info(state2, kvno, (P), state->info); \ -- if (ret != 0) { \ -- return ADS_ERROR_KRB5(ret); \ -- } -- -- /* Add ACCOUNTNAME$ entries */ -- switch (keytabptr->spn_spec) { -- case SPN_SPEC_DEFAULT: -- ADD_INFO(state->info->account_name); -- break; -- case SPN_SPEC_SYNC: -- for (i = 0; i < state->ad_num_spns; i++) { -- ADD_INFO(state->ad_spn_array[i]); -- } -- break; -- case SPN_SPEC_FULL: -- for (i = 0; i < keytabptr->num_spn_spec; i++) { -- ADD_INFO(keytabptr->spn_spec_array[i]); -- } -- break; -- case SPN_SPEC_PREFIX: -- for (i = 0; i < keytabptr->num_spn_spec; i++) { -- princ_s = talloc_asprintf(talloc_tos(), -- "%s/%s@%s", -- keytabptr->spn_spec_array[i], -- lp_netbios_name(), -- lp_realm()); -- if (princ_s == NULL) { -- return ADS_ERROR_KRB5(ENOMEM); -- } -- ADD_INFO(princ_s); -- -- if (!keytabptr->netbios_aliases) { -- goto additional_dns_hostnames; -- } -- for (netbios_alias = lp_netbios_aliases(); -- netbios_alias != NULL && *netbios_alias != NULL; -- netbios_alias++) -- { -- /* Add PREFIX/netbiosname@REALM */ -- princ_s = talloc_asprintf( -- talloc_tos(), -- "%s/%s@%s", -- keytabptr->spn_spec_array[i], -- *netbios_alias, -- lp_realm()); -- if (princ_s == NULL) { -- return ADS_ERROR_KRB5(ENOMEM); -- } -- ADD_INFO(princ_s); -- -- /* Add PREFIX/netbiosname.domainname@REALM */ -- princ_s = talloc_asprintf( -- talloc_tos(), -- "%s/%s.%s@%s", -- keytabptr->spn_spec_array[i], -- *netbios_alias, -- lp_dnsdomain(), -- lp_realm()); -- if (princ_s == NULL) { -- return ADS_ERROR_KRB5(ENOMEM); -- } -- ADD_INFO(princ_s); -- } -- --additional_dns_hostnames: -- if (!keytabptr->additional_dns_hostnames) { -- continue; -- } -- for (addl_hostnames = lp_additional_dns_hostnames(); -- addl_hostnames != NULL && *addl_hostnames != NULL; -- addl_hostnames++) -- { -- /* Add PREFIX/netbiosname@REALM */ -- princ_s = talloc_asprintf( -- talloc_tos(), -- "%s/%s@%s", -- keytabptr->spn_spec_array[i], -- *addl_hostnames, -- lp_realm()); -- if (princ_s == NULL) { -- return ADS_ERROR_KRB5(ENOMEM); -- } -- ADD_INFO(princ_s); -- } -+ for (k = 0; k < SPN_SPEC_MAX; k++) { -+ status = pw2kt_process_specifier(state, state2, keytabptr, k); -+ if (!ADS_ERR_OK(status)) { -+ return status; - } -- break; -- default: -- return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); - } - - ret = smb_krb5_kt_open(state2->context, -@@ -718,7 +854,7 @@ sync_kvno: - return ADS_ERROR_KRB5(ret); - } - --static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_state *state) -+static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_global_state *state) - { - ADS_STATUS status; - LDAPMessage *res = NULL; -@@ -762,7 +898,7 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_state *state) - "msDS-SupportedEncryptionTypes", - &state->ad_etypes); - if (!ok) { -- DBG_WARNING("Failed to determine encryption types.\n"); -+ DBG_ERR("Failed to determine encryption types.\n"); - ads_msgfree(ads, res); - TALLOC_FREE(tmp_ctx); - return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); -@@ -773,7 +909,7 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_state *state) - uint32_t kvno = -1; - ok = ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno); - if (!ok) { -- DBG_WARNING("Failed to determine the system's kvno.\n"); -+ DBG_ERR("Failed to determine the system's kvno.\n"); - ads_msgfree(ads, res); - TALLOC_FREE(tmp_ctx); - return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); -@@ -787,8 +923,34 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_state *state) - res, - "servicePrincipalName", - &state->ad_num_spns); -- if (state->ad_spn_array == NULL) { -- DBG_WARNING("Failed to determine SPNs.\n"); -+ if (state->ad_spn_array == NULL || state->ad_num_spns == 0) { -+ DBG_ERR("Failed to determine servicePrincipalName.\n"); -+ ads_msgfree(ads, res); -+ TALLOC_FREE(tmp_ctx); -+ return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); -+ } -+ } -+ -+ if (state->sync_upn) { -+ state->ad_upn = ads_pull_string(ads, -+ state, -+ res, -+ "userPrincipalName"); -+ if (state->ad_upn == NULL) { -+ DBG_ERR("Failed to determine userPrincipalName.\n"); -+ ads_msgfree(ads, res); -+ TALLOC_FREE(tmp_ctx); -+ return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); -+ } -+ } -+ -+ if (state->sync_sam_account) { -+ state->ad_sam_account = ads_pull_string(ads, -+ state, -+ res, -+ "sAMAccountName"); -+ if (state->ad_sam_account == NULL) { -+ DBG_ERR("Failed to determine sAMAccountName.\n"); - ads_msgfree(ads, res); - TALLOC_FREE(tmp_ctx); - return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); -@@ -864,13 +1026,14 @@ NTSTATUS sync_pw2keytabs(void) - TALLOC_CTX *frame = talloc_stackframe(); - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); -- struct pw2kt_state *state = NULL; -+ struct pw2kt_global_state *state = NULL; - const char **line = NULL; - const char **lp_ptr = NULL; - const char *pwsync_script = NULL; - NTSTATUS status_nt; - ADS_STATUS status_ads; - int i; -+ size_t num_keytabs; - - DBG_DEBUG("Syncing machine password from secrets to keytabs.\n"); - -@@ -879,7 +1042,7 @@ NTSTATUS sync_pw2keytabs(void) - return NT_STATUS_OK; /* nothing todo */ - } - -- state = talloc_zero(frame, struct pw2kt_state); -+ state = talloc_zero(frame, struct pw2kt_global_state); - if (state == NULL) { - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; -@@ -921,7 +1084,9 @@ NTSTATUS sync_pw2keytabs(void) - } - - params_ready: -- if (state->sync_etypes || state->sync_kvno || state->sync_spns) { -+ if (state->sync_etypes || state->sync_kvno || state->sync_spns || -+ state->sync_upn || state->sync_sam_account) -+ { - status_ads = pw2kt_get_dc_info(state); - if (!ADS_ERR_OK(status_ads)) { - DBG_WARNING("cannot read from DC\n"); -@@ -929,9 +1094,10 @@ params_ready: - return NT_STATUS_INTERNAL_ERROR; - } - } else { -- DBG_DEBUG("No 'sync_etypes', 'sync_kvno' and 'sync_spns' in " -- "parameter 'sync machine password to keytab' => " -- "no need to talk to DC.\n"); -+ DBG_DEBUG("No 'sync_etypes', 'sync_kvno', 'sync_spns', " -+ "'sync_upn' and 'sync_sam_account' in parameter " -+ "'sync machine password to keytab' => no need to " -+ "talk to DC.\n"); - } - - if (!secrets_init()) { -@@ -951,7 +1117,8 @@ params_ready: - return status_nt; - } - -- for (i = 0; i < state->num_keytabs; i++) { -+ num_keytabs = talloc_array_length(state->keytabs); -+ for (i = 0; i < num_keytabs; i++) { - status_ads = pw2kt_process_keytab(state, &state->keytabs[i]); - if (!ADS_ERR_OK(status_ads)) { - TALLOC_FREE(frame); -diff --git a/source3/script/tests/test_update_keytab.sh b/source3/script/tests/test_update_keytab.sh -index 2c38b53ccca..82c64984787 100755 ---- a/source3/script/tests/test_update_keytab.sh -+++ b/source3/script/tests/test_update_keytab.sh -@@ -20,208 +20,416 @@ samba_net="$BINDIR/net $CONFIGURATION" - samba_rpcclient="$BINDIR/rpcclient $CONFIGURATION" - smbclient="${BINDIR}/smbclient" - --keytabs_sync_kvno="keytab0k keytab1k keytab2k keytab3k" -+keytabs_sync_kvno="keytab0k keytab1k keytab2k keytab3k keytab4k" - keytabs_nosync_kvno="keytab0 keytab1 keytab2 keytab3" - keytabs_all="$keytabs_sync_kvno $keytabs_nosync_kvno" - --# default, no specifiers -+# Generate the next ~300 lines for keytab templates using these steps: -+# make testenv SELFTEST_TESTENV="ad_member_idmap_nss:local" -+# source3/script/tests/test_update_keytab.sh ADDOMAIN --configfile=st/ad_member_idmap_nss/lib/server.conf -+# and finally source it from the vim editor -+# :r! for k in keytab0 keytab0k keytab1 keytab1k keytab2 keytab2k keytab3 keytab3k keytab4k ; do (echo $k=\"\\; bin/net --configfile=st/ad_member_idmap_nss/lib/server.conf ads keytab list /path/st/ad_member_idmap_nss/$k |sort -k3 |grep -v Vno|sed 's/\$/\\$/'; echo '";'; echo ); done -+ - keytab0="\ -- -1 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - -1 arcfour-hmac-md5 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - -2 arcfour-hmac-md5 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - -3 arcfour-hmac-md5 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ -1 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# sync_kvno=yes - keytab0k="\ -- 5 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# sync_spns=yes - keytab1="\ -- -1 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# sync_spns=yes:sync_kvno=yes - keytab1k="\ -- 5 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 HOST/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 HOST/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 RestrictedKrbHost/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# spn_prefixes=imap,smtp - keytab2="\ -+ -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 imap/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 imap/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 imap/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 imap/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 imap/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 imap/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 imap/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 imap/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 imap/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 smtp/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 smtp/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 smtp/NETBIOS3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# spn_prefixes=imap,smtp:sync_kvno=yes - keytab2k="\ -- 5 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM - "; - --# spns=wurst/brot\@$dcvars->{REALM} - keytab3="\ -+ -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - "; - --# spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno=yes - keytab3k="\ -- 5 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM -- 3 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+"; -+ -+keytab4k="\ -+ 4 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 host/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 imap/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/host1.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/host2.other.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/NETBIOS1@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/netbios1.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/NETBIOS2@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/netbios2.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/NETBIOS3@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 smtp/netbios3.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst2/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 4 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 5 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM -+ 6 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - "; - - # find the biggest vno and store it into global variable vno -@@ -289,9 +497,9 @@ SED2="s/^ \+-\?[0-9]\+ \+//" - - compare_keytabs_sync_kvno() - { -- sed "$SED1" < "$1" | sort -k1rn -k3 | sed "$SED2" > "${1}.sync_kvno" -- sed "$SED1" < "$2" | sort -k1rn -k3 | sed "$SED2" > "${2}.sync_kvno" -- diff --ignore-case "${1}.sync_kvno" "${2}.sync_kvno" -+ sed "$SED1" < "$1" | sed "$SED2" | sort > "${1}.sync_kvno" -+ sed "$SED1" < "$2" | sed "$SED2" | sort > "${2}.sync_kvno" -+ diff "${1}.sync_kvno" "${2}.sync_kvno" - return $? - } - -@@ -299,7 +507,7 @@ compare_keytabs_nosync_kvno() - { - sed "$SED1" < "$1" | sort -k1rn -k3 > "${1}.nosync_kvno" - sed "$SED1" < "$2" | sort -k1rn -k3 > "${2}.nosync_kvno" -- diff --ignore-case "${1}.nosync_kvno" "${2}.nosync_kvno" -+ diff "${1}.nosync_kvno" "${2}.nosync_kvno" - return $? - } - -@@ -391,6 +599,7 @@ printf '%s' "$keytab2" > "$TMPDIR/keytab2_template" - printf '%s' "$keytab2k" > "$TMPDIR/keytab2k_template" - printf '%s' "$keytab3" > "$TMPDIR/keytab3_template" - printf '%s' "$keytab3k" > "$TMPDIR/keytab3k_template" -+printf '%s' "$keytab4k" > "$TMPDIR/keytab4k_template" - - # Other approach could e.g. compare first six entries from the template. - # The 6 entries correspond to password and old_password, each has 3 enc. types. --- -2.51.0 - - -From f1e0fce49fbd1890da053d05c8511010cb7f2911 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Tue, 14 Jan 2025 11:29:54 +0100 -Subject: [PATCH 04/43] docs-xml:smbdotconf: Document new options for 'sync - machinepassword to keytab' -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15759 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Andreas Schneider -Reviewed-by: Alexander Bokovoy - -Autobuild-User(master): Pavel Filipensky -Autobuild-Date(master): Thu Feb 13 18:45:21 UTC 2025 on atb-devel-224 - -(cherry picked from commit 7a662e097be5e0d3f7779fa544486968b8f57063) ---- - docs-xml/manpages/net.8.xml | 24 +++++------ - .../security/syncmachinepasswordtokeytab.xml | 42 ++++++++++++------- - 2 files changed, 38 insertions(+), 28 deletions(-) - -diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml -index f388644172f..8091368a48e 100644 ---- a/docs-xml/manpages/net.8.xml -+++ b/docs-xml/manpages/net.8.xml -@@ -1549,29 +1549,25 @@ to show in the result. - - - Since Samba 4.21.0, keytab file is created as specified in . The keytab is created only for -+name="sync machine password to keytab"/> . The keytab can be created only when -+machine password is available in secrets.tdb, i.e. only for - secrets only and - secrets and keytab. With - the smb.conf default values for secrets - only and - (default is empty) the keytab is not generated at all. Keytab with a default --name and SPNs synced from AD is created for secrets and keytab if is missing. -+name containing: SPNs synced from AD, account name COMPUTER$ and principal -+host/dns_hostname is created for secrets -+and keytab if is missing. - - --Till Samba 4.20.0, two more entries were created by default: the machinename of --the client (ending with '$') and the UPN (host/domain@REALM). If these two --entries are still needed, each must be specified in an own keytab file. --Example below will generate three keytab files that contain SPNs synced from --AD, host UPN and machine$ SPN: -+Till Samba 4.20, these entries were created by default: the account name -+COMPUTER$, 'host' principal and SPNs synced from AD. Example below generates -+such keytab ('host' is added implicitly): - - -- --/etc/krb5.keytab0:sync_spns:machine_password, --/etc/krb5.keytab1:spns=host/smb.com@SMB.COM:machine_password, --/etc/krb5.keytab2:account_name:machine_password -- -+/etc/krb5.keytab:account_name:sync_spns:sync_kvno:machine_password - - - No changes are made to the computer AD account. -diff --git a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -index f7dc30023d4..02eaf3162c0 100644 ---- a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -+++ b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -@@ -24,36 +24,49 @@ synchronization. - - Each string has this form: - --absolute_path_to_keytab:spn_spec[:sync_etypes][:sync_kvno][:netbios_aliases][:additional_dns_hostnames][:machine_password] -+absolute_path_to_keytab:spn_spec[:spn_spec]*[:sync_etypes][:sync_kvno][:netbios_aliases][:additional_dns_hostnames][:machine_password] - - --where spn_spec can have exactly one of these four forms: -+spn_spec can be specified multiple times (separated using ':') and each spn_spec can have exactly one of these forms: - - account_name -+sync_account_name -+sync_upn - sync_spns - spn_prefixes=value1[,value2[...]] - spns=value1[,value2[...]] - --No other combinations are allowed. - - - --Specifiers: -+Every keytab contains the 'host' principal and principals according the specification below: - --account_name - creates entry using principal 'computer$@REALM'. --sync_spns - uses principals received from AD DC. --spn_prefixes - creates principals from the prefixes and adds netbios_aliases or additional_dns_hostnames if specified. --spns - creates only the principals defined in the list. -+account_name - COMPUTER$@REALM -+sync_account_name - uses attribute "sAMAccountName" from AD -+host - always present, no need to specify it explicitly -+ the 'host' principal is created for the same variants (netbios name, dns hostname, netbiosalias, additional_dns_hostname) as in spn_prefixes -+sync_upn - uses attribute "userPrincipalName" (if exists in AD) -+sync_spns - uses attribute "servicePrincipalName" (if exists in AD) -+spn_prefixes - creates these two principals from each prefix. e.g.: -+ prefix/@REALM -+ prefix/@REALM -+ with :netbios_aliases for each netbiosalias in -+ prefix/netbiosalias@REALM -+ prefix/netbiosalias.dnsdomain@REALM -+ with :additional_dns_hostnames for each additionaldnshostname in -+ prefix/additionaldnshostname@REALM -+spns - creates only the principals defined in the list - -+'account_name' and 'sync_account_name' are the same, just the source differs (secrets.tdb vs. AD). - - - - Options: - --sync_etypes - parameter "msDS-SupportedEncryptionTypes" is read from DC and is used to find the highest common enc type for AD and KRB5 lib. --sync_kvno - the key version number ("msDS-KeyVersionNumber") is synchronized from DC, otherwise is set to -1. --netbios_aliases - evaluated only for SPN_SPEC_PREFIX. If present, PREFIX/netbiosname@REALM and PREFIX/netbiosname.domainname@REALM are added for each alias. See --additional_dns_hostnames - evaluated only for SPN_SPEC_PREFIX. If present, PREFIX/dnshostname@REALM is added for each dns name. See -+sync_etypes - attribute "msDS-SupportedEncryptionTypes" is read from AD and is used to find the highest common enc type for AD and KRB5 lib. -+sync_kvno - attribute "msDS-KeyVersionNumber" from AD is used to set KVNO. If this option is missing, KVNO is set to -1. -+netbios_aliases - evaluated only for spn_prefixes (see details above) and for the 'host' principal. -+additional_dns_hostnames - evaluated only for spn_prefixes (see details above) and for the 'host' principal. - machine_password - mandatory, if missing the entry is ignored. For future use. - - -@@ -68,7 +81,8 @@ Example: - "/path/to/keytab4:spn_prefixes=imap,smtp:machine_password", - "/path/to/keytab5:spn_prefixes=imap,smtp:netbios_aliases:additional_dns_hostnames:sync_kvno:machine_password", - "/path/to/keytab6:spns=wurst/brot@REALM:machine_password", --"/path/to/keytab7:spns=wurst/brot@REALM,wurst2/brot@REALM:sync_kvno:machine_password" -+"/path/to/keytab7:spns=wurst/brot@REALM,wurst2/brot@REALM:sync_kvno:machine_password", -+"/path/to/keytab8:account_name:sync_account_name:host:sync_upn:sync_spns:spn_prefixes=cifs,http:spns=wurst/brot@REALM:sync_kvno:machine_password" - - If sync_etypes or sync_kvno or sync_spns is present then winbind connects to DC. For "offline domain join" it might be useful not to use these options. - -@@ -80,7 +94,7 @@ If no value is present and is different - - - winbind uses value -- /path/to/keytab:sync_spns:sync_kvno:machine_password -+ /path/to/keytab:host:account_name:sync_spns:sync_kvno:machine_password - where the path to the keytab is obtained either from the krb5 library or from - . - --- -2.51.0 - - -From 4dc163e87824aac33107767881d4a47033c5d9dd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Fri, 14 Feb 2025 17:28:54 +0100 -Subject: [PATCH 05/43] s3:libads: Remove specifier for 'host' principal from - 'sync machine password to keytab' -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use specifier 'spn_prefixes=host' instead of 'host' - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15759 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Stefan Metzmacher -(cherry picked from commit ccc3b2b2fba7b5d223c79bffc0f655490aed19cf) ---- - selftest/target/Samba3.pm | 6 +-- - source3/libads/kerberos_keytab.c | 21 +++------- - source3/script/tests/test_update_keytab.sh | 48 ---------------------- - 3 files changed, 9 insertions(+), 66 deletions(-) - -diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm -index cc4498ff36e..6650690fbb7 100755 ---- a/selftest/target/Samba3.pm -+++ b/selftest/target/Samba3.pm -@@ -804,11 +804,11 @@ sub provision_ad_member - \"$prefix_abs/keytab0k:account_name:sync_kvno:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab1:sync_spns:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab1k:sync_spns:sync_kvno:machine_password:sync_etypes\", \\ -- \"$prefix_abs/keytab2:spn_prefixes=imap,smtp:additional_dns_hostnames:netbios_aliases:machine_password:sync_etypes\", \\ -- \"$prefix_abs/keytab2k:spn_prefixes=imap,smtp:additional_dns_hostnames:sync_kvno:machine_password:sync_etypes\", \\ -+ \"$prefix_abs/keytab2:spn_prefixes=host,imap,smtp:additional_dns_hostnames:netbios_aliases:machine_password:sync_etypes\", \\ -+ \"$prefix_abs/keytab2k:spn_prefixes=host,imap,smtp:additional_dns_hostnames:sync_kvno:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab3:spns=wurst/brot\@$dcvars->{REALM}:machine_password:sync_etypes\", \\ - \"$prefix_abs/keytab3k:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\", \\ -- \"$prefix_abs/keytab4k:account_name:sync_account_name:spn_prefixes=imap,smtp:additional_dns_hostnames:netbios_aliases:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\" -+ \"$prefix_abs/keytab4k:account_name:sync_account_name:spn_prefixes=host,imap,smtp:additional_dns_hostnames:netbios_aliases:spns=wurst/brot\@$dcvars->{REALM},wurst1/brot\@$dcvars->{REALM},wurst2/brot\@$dcvars->{REALM}:sync_kvno:machine_password:sync_etypes\" - "; - } - -diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c -index 619a7bda0d4..5913db299ad 100644 ---- a/source3/libads/kerberos_keytab.c -+++ b/source3/libads/kerberos_keytab.c -@@ -44,7 +44,6 @@ - enum spn_spec_type { - SPN_SPEC_ACCOUNT_NAME, - SPN_SPEC_SYNC_ACCOUNT_NAME, -- SPN_SPEC_HOST, - SPN_SPEC_SYNC_UPN, - SPN_SPEC_SYNC_SPNS, - SPN_SPEC_FULL, -@@ -164,8 +163,6 @@ static ADS_STATUS pw2kt_scan_spec(TALLOC_CTX *ctx, - } else if (strequal(option, "sync_account_name")) { - spec_type = SPN_SPEC_SYNC_ACCOUNT_NAME; - gstate->sync_sam_account = true; -- } else if (strequal(option, "host")) { -- spec_type = SPN_SPEC_HOST; - } else if (strequal(option, "sync_upn")) { - spec_type = SPN_SPEC_SYNC_UPN; - gstate->sync_upn = true; -@@ -251,9 +248,6 @@ static ADS_STATUS pw2kt_scan_line(const char *line, - *olist = 0; - olist++; - -- /* Always add 'host' principal */ -- desc->spec_array[SPN_SPEC_HOST].is_set = true; -- - /* Entries are separated via ':' */ - while ((tmp = strchr_m(olist, ':')) != NULL) { - *tmp = 0; -@@ -275,7 +269,8 @@ static ADS_STATUS pw2kt_scan_line(const char *line, - /* - * Fill struct pw2kt_global_state with defaults if - * "sync machine password to keytab" is missing in smb.conf -- * Creates 1 keytab with 3 SPN specifiers (sync_spns, account_name, host). -+ * Creates 1 keytab with these SPN specifiers: -+ * sync_spns:account_name:spn_prefixes=host:sync_kvno:machine_password - */ - static ADS_STATUS pw2kt_default_cfg(const char *name, - struct pw2kt_global_state *state) -@@ -302,9 +297,11 @@ static ADS_STATUS pw2kt_default_cfg(const char *name, - - desc->spec_array[SPN_SPEC_SYNC_SPNS].is_set = true; - desc->spec_array[SPN_SPEC_ACCOUNT_NAME].is_set = true; -- desc->spec_array[SPN_SPEC_HOST].is_set = true; -+ desc->spec_array[SPN_SPEC_PREFIX].is_set = true; - -- return ADS_SUCCESS; -+ return pw2kt_add_val(state->keytabs, -+ &desc->spec_array[SPN_SPEC_PREFIX], -+ "host"); - } - - /* -@@ -590,12 +587,6 @@ static ADS_STATUS pw2kt_process_specifier(struct pw2kt_global_state *gstate, - case SPN_SPEC_SYNC_ACCOUNT_NAME: - ADD_INFO(gstate->ad_sam_account); - break; -- case SPN_SPEC_HOST: -- status = pw2kt_add_prefix(gstate, state2, keytabptr, "host"); -- if (!ADS_ERR_OK(status)) { -- return status; -- } -- break; - case SPN_SPEC_SYNC_UPN: - if (gstate->ad_upn != NULL) { - ADD_INFO(gstate->ad_upn); -diff --git a/source3/script/tests/test_update_keytab.sh b/source3/script/tests/test_update_keytab.sh -index 82c64984787..21edf8b8882 100755 ---- a/source3/script/tests/test_update_keytab.sh -+++ b/source3/script/tests/test_update_keytab.sh -@@ -40,48 +40,18 @@ keytab0="\ - -2 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - -3 aes128-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- -1 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 arcfour-hmac-md5 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes128-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 arcfour-hmac-md5 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes128-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - - keytab0k="\ - 4 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM - 6 aes256-cts-hmac-sha1-96 ADMEMIDMAPNSS\$@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - "; - - keytab1="\ -- -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -@@ -118,15 +88,9 @@ keytab1="\ - "; - - keytab1k="\ -- 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM - 6 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 6 aes256-cts-hmac-sha1-96 HOST/ADMEMIDMAPNSS.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -@@ -295,24 +259,12 @@ keytab2k="\ - "; - - keytab3="\ -- -1 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- -1 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -2 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- -3 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - -1 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - -2 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - -3 aes256-cts-hmac-sha1-96 wurst/brot@ADDOM.SAMBA.EXAMPLE.COM - "; - - keytab3k="\ -- 4 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/ADMEMIDMAPNSS@ADDOM.SAMBA.EXAMPLE.COM -- 4 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 5 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM -- 6 aes256-cts-hmac-sha1-96 host/admemidmapnss.addom.samba.example.com@ADDOM.SAMBA.EXAMPLE.COM - 4 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM - 5 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM - 6 aes256-cts-hmac-sha1-96 wurst1/brot@ADDOM.SAMBA.EXAMPLE.COM --- -2.51.0 - - -From 8bb9f6f5d9f5db755dfd950260288dfd746cfbb6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Fri, 14 Feb 2025 17:27:26 +0100 -Subject: [PATCH 06/43] docs: Update documentation for 'sync machine password - to keytab' -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Use specifier 'spn_prefixes=host' instead of 'host' - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15759 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Stefan Metzmacher - -Autobuild-User(master): Pavel Filipensky -Autobuild-Date(master): Sat Feb 15 19:21:56 UTC 2025 on atb-devel-224 - -(cherry picked from commit 7cae7aad1ca6dcd5e0a3a102f36af74fa49a2c2b) ---- - docs-xml/manpages/net.8.xml | 4 ++-- - .../security/syncmachinepasswordtokeytab.xml | 11 +++++------ - 2 files changed, 7 insertions(+), 8 deletions(-) - -diff --git a/docs-xml/manpages/net.8.xml b/docs-xml/manpages/net.8.xml -index 8091368a48e..a5f004d6e12 100644 ---- a/docs-xml/manpages/net.8.xml -+++ b/docs-xml/manpages/net.8.xml -@@ -1564,10 +1564,10 @@ keytab"/> is missing. - - Till Samba 4.20, these entries were created by default: the account name - COMPUTER$, 'host' principal and SPNs synced from AD. Example below generates --such keytab ('host' is added implicitly): -+such keytab: - - --/etc/krb5.keytab:account_name:sync_spns:sync_kvno:machine_password -+/etc/krb5.keytab:spn_prefixes=host:account_name:sync_spns:sync_kvno:machine_password - - - No changes are made to the computer AD account. -diff --git a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -index 02eaf3162c0..ec3fffc1119 100644 ---- a/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -+++ b/docs-xml/smbdotconf/security/syncmachinepasswordtokeytab.xml -@@ -39,12 +39,10 @@ spns=value1[,value2[...]] - - - --Every keytab contains the 'host' principal and principals according the specification below: -+Every keytab contains principals according the specification below: - - account_name - COMPUTER$@REALM - sync_account_name - uses attribute "sAMAccountName" from AD --host - always present, no need to specify it explicitly -- the 'host' principal is created for the same variants (netbios name, dns hostname, netbiosalias, additional_dns_hostname) as in spn_prefixes - sync_upn - uses attribute "userPrincipalName" (if exists in AD) - sync_spns - uses attribute "servicePrincipalName" (if exists in AD) - spn_prefixes - creates these two principals from each prefix. e.g.: -@@ -55,6 +53,7 @@ spn_prefixes - creates these two principals from each prefix. e.g.: - prefix/netbiosalias.dnsdomain@REALM - with :additional_dns_hostnames for each additionaldnshostname in - prefix/additionaldnshostname@REALM -+ - 'host' principal should be created using specifier spn_prefixes - spns - creates only the principals defined in the list - - 'account_name' and 'sync_account_name' are the same, just the source differs (secrets.tdb vs. AD). -@@ -65,8 +64,8 @@ Options: - - sync_etypes - attribute "msDS-SupportedEncryptionTypes" is read from AD and is used to find the highest common enc type for AD and KRB5 lib. - sync_kvno - attribute "msDS-KeyVersionNumber" from AD is used to set KVNO. If this option is missing, KVNO is set to -1. --netbios_aliases - evaluated only for spn_prefixes (see details above) and for the 'host' principal. --additional_dns_hostnames - evaluated only for spn_prefixes (see details above) and for the 'host' principal. -+netbios_aliases - evaluated only for spn_prefixes (see details above). -+additional_dns_hostnames - evaluated only for spn_prefixes (see details above). - machine_password - mandatory, if missing the entry is ignored. For future use. - - -@@ -82,7 +81,7 @@ Example: - "/path/to/keytab5:spn_prefixes=imap,smtp:netbios_aliases:additional_dns_hostnames:sync_kvno:machine_password", - "/path/to/keytab6:spns=wurst/brot@REALM:machine_password", - "/path/to/keytab7:spns=wurst/brot@REALM,wurst2/brot@REALM:sync_kvno:machine_password", --"/path/to/keytab8:account_name:sync_account_name:host:sync_upn:sync_spns:spn_prefixes=cifs,http:spns=wurst/brot@REALM:sync_kvno:machine_password" -+"/path/to/keytab8:sync_account_name:sync_upn:sync_spns:spn_prefixes=host,cifs,http:spns=wurst/brot@REALM:sync_kvno:machine_password" - - If sync_etypes or sync_kvno or sync_spns is present then winbind connects to DC. For "offline domain join" it might be useful not to use these options. - --- -2.51.0 - - -From 205bed2a3a8cb8d2ff9651244aab02b2f9f602ae Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Wed, 15 Jan 2025 10:21:19 -0800 -Subject: [PATCH 07/43] auth: Add missing talloc_free() in error code path. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15782 - -Signed-off-by: Jeremy Allison -Reviewed-by: Guenther Deschner - -Autobuild-User(master): Günther Deschner -Autobuild-Date(master): Thu Jan 16 14:32:39 UTC 2025 on atb-devel-224 - -(cherry picked from commit c514ce8dcadcbbf0d86f3038d2be0f9253a76b75) ---- - auth/kerberos/kerberos_pac.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/auth/kerberos/kerberos_pac.c b/auth/kerberos/kerberos_pac.c -index b6272ac15eb..1f7d3e7ef26 100644 ---- a/auth/kerberos/kerberos_pac.c -+++ b/auth/kerberos/kerberos_pac.c -@@ -360,6 +360,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - if (ret) { - DEBUG(5, ("PAC Decode: Failed to verify the service " - "signature: %s\n", error_message(ret))); -+ talloc_free(tmp_ctx); - return NT_STATUS_ACCESS_DENIED; - } - --- -2.51.0 - - -From b531c84559e2391c38e4c7640610462046d2d7c6 Mon Sep 17 00:00:00 2001 -From: Jeremy Allison -Date: Thu, 16 Jan 2025 16:12:31 -0800 -Subject: [PATCH 08/43] auth: Cleanup exit code paths in kerberos_decode_pac(). -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -One more memory leak missed and now fixed. tmp_ctx -must be freed once the pac data is talloc_move'd. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15782 - -Signed-off-by: Jeremy Allison -Reviewed-by: Jennifer Sutton -Reviewed-by: Christian Ambach -Reviewed-by: Guenther Deschner - -Autobuild-User(master): Günther Deschner -Autobuild-Date(master): Fri Jan 17 12:01:47 UTC 2025 on atb-devel-224 - -(cherry picked from commit f9eb0b248da0689c82656f3e482161c45749afb6) ---- - auth/kerberos/kerberos_pac.c | 88 ++++++++++++++++++------------------ - 1 file changed, 43 insertions(+), 45 deletions(-) - -diff --git a/auth/kerberos/kerberos_pac.c b/auth/kerberos/kerberos_pac.c -index 1f7d3e7ef26..4c61cfe838f 100644 ---- a/auth/kerberos/kerberos_pac.c -+++ b/auth/kerberos/kerberos_pac.c -@@ -137,7 +137,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - time_t tgs_authtime, - struct PAC_DATA **pac_data_out) - { -- NTSTATUS status; -+ NTSTATUS status = NT_STATUS_NO_MEMORY; - enum ndr_err_code ndr_err; - krb5_error_code ret; - DATA_BLOB modified_pac_blob; -@@ -173,8 +173,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - kdc_sig_wipe = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA); - srv_sig_wipe = talloc(tmp_ctx, struct PAC_SIGNATURE_DATA); - if (!pac_data_raw || !pac_data || !kdc_sig_wipe || !srv_sig_wipe) { -- talloc_free(tmp_ctx); -- return NT_STATUS_NO_MEMORY; -+ status = NT_STATUS_NO_MEMORY; -+ goto out; - } - - ndr_err = ndr_pull_struct_blob(&pac_data_blob, pac_data, pac_data, -@@ -183,15 +183,14 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't parse the PAC: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - if (pac_data->num_buffers < 4) { - /* we need logon_info, service_key and kdc_key */ - DEBUG(0,("less than 4 PAC buffers\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - ndr_err = ndr_pull_struct_blob( -@@ -201,15 +200,14 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't parse the PAC: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - if (pac_data_raw->num_buffers < 4) { - /* we need logon_info, service_key and kdc_key */ - DEBUG(0,("less than 4 PAC buffers\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - if (pac_data->num_buffers != pac_data_raw->num_buffers) { -@@ -217,8 +215,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - DEBUG(0, ("misparse! PAC_DATA has %d buffers while " - "PAC_DATA_RAW has %d\n", pac_data->num_buffers, - pac_data_raw->num_buffers)); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - for (i=0; i < pac_data->num_buffers; i++) { -@@ -229,8 +227,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - DEBUG(0, ("misparse! PAC_DATA buffer %d has type " - "%d while PAC_DATA_RAW has %d\n", i, - data_buf->type, raw_buf->type)); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - switch (data_buf->type) { - case PAC_TYPE_LOGON_INFO: -@@ -263,26 +261,26 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - - if (!logon_info) { - DEBUG(0,("PAC no logon_info\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - if (!logon_name) { - DEBUG(0,("PAC no logon_name\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - if (!srv_sig_ptr || !srv_sig_blob) { - DEBUG(0,("PAC no srv_key\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - if (!kdc_sig_ptr || !kdc_sig_blob) { - DEBUG(0,("PAC no kdc_key\n")); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - /* Find and zero out the signatures, -@@ -297,8 +295,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't parse the KDC signature: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - ndr_err = ndr_pull_struct_blob( -@@ -308,8 +305,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't parse the SRV signature: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - /* Now zero the decoded structure */ -@@ -326,8 +322,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't repack the KDC signature: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - ndr_err = ndr_push_struct_blob( - srv_sig_blob, pac_data_raw, srv_sig_wipe, -@@ -336,8 +331,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't repack the SRV signature: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - /* push out the whole structure, but now with zero'ed signatures */ -@@ -348,8 +342,7 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - status = ndr_map_error2ntstatus(ndr_err); - DEBUG(0,("can't repack the RAW PAC: %s\n", - nt_errstr(status))); -- talloc_free(tmp_ctx); -- return status; -+ goto out; - } - - if (service_keyblock) { -@@ -360,8 +353,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - if (ret) { - DEBUG(5, ("PAC Decode: Failed to verify the service " - "signature: %s\n", error_message(ret))); -- talloc_free(tmp_ctx); -- return NT_STATUS_ACCESS_DENIED; -+ status = NT_STATUS_ACCESS_DENIED; -+ goto out; - } - - if (krbtgt_keyblock) { -@@ -371,8 +364,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - if (ret) { - DEBUG(1, ("PAC Decode: Failed to verify the KDC signature: %s\n", - smb_get_krb5_error_message(context, ret, tmp_ctx))); -- talloc_free(tmp_ctx); -- return NT_STATUS_ACCESS_DENIED; -+ status = NT_STATUS_ACCESS_DENIED; -+ goto out; - } - } - } -@@ -388,8 +381,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - nt_time_string(tmp_ctx, logon_name->logon_time))); - DEBUG(2, ("PAC Decode: Ticket: %s\n", - nt_time_string(tmp_ctx, tgs_authtime_nttime))); -- talloc_free(tmp_ctx); -- return NT_STATUS_ACCESS_DENIED; -+ status = NT_STATUS_ACCESS_DENIED; -+ goto out; - } - } - -@@ -401,8 +394,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - if (ret) { - DEBUG(2, ("Could not unparse name from ticket to match with name from PAC: [%s]:%s\n", - logon_name->account_name, error_message(ret))); -- talloc_free(tmp_ctx); -- return NT_STATUS_INVALID_PARAMETER; -+ status = NT_STATUS_INVALID_PARAMETER; -+ goto out; - } - - bool_ret = strcmp(client_principal_string, logon_name->account_name) == 0; -@@ -413,8 +406,8 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - logon_name->account_name, - client_principal_string)); - SAFE_FREE(client_principal_string); -- talloc_free(tmp_ctx); -- return NT_STATUS_ACCESS_DENIED; -+ status = NT_STATUS_ACCESS_DENIED; -+ goto out; - } - SAFE_FREE(client_principal_string); - -@@ -435,10 +428,15 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, - } - - if (pac_data_out) { -- *pac_data_out = talloc_steal(mem_ctx, pac_data); -+ *pac_data_out = talloc_move(mem_ctx, &pac_data); - } - -- return NT_STATUS_OK; -+ status = NT_STATUS_OK; -+ -+ out: -+ -+ TALLOC_FREE(tmp_ctx); -+ return status; - } - - NTSTATUS kerberos_pac_logon_info(TALLOC_CTX *mem_ctx, --- -2.51.0 - - -From ffdb675281389635e34b6f06d68222db5f2e83a5 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 9 Jan 2025 08:57:17 +0100 -Subject: [PATCH 09/43] dbwrap: check for option "tdb_hash_size:DBNAME.tdb" in - db_open() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 7eb135c42d530a16e80e165d9e8e99d920797f12) ---- - source3/lib/dbwrap/dbwrap_open.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c -index 52c8a94aeff..91556f22819 100644 ---- a/source3/lib/dbwrap/dbwrap_open.c -+++ b/source3/lib/dbwrap/dbwrap_open.c -@@ -80,6 +80,11 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx, - base = name; - } - -+ hash_size = lp_parm_int(GLOBAL_SECTION_SNUM, -+ "tdb_hash_size", -+ base, -+ hash_size); -+ - if (tdb_flags & TDB_CLEAR_IF_FIRST) { - bool try_readonly = false; - --- -2.51.0 - - -From fd7331e9e50c130d98b490c3cc1d8fa77ec575a1 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 9 Jan 2025 12:27:43 +0100 -Subject: [PATCH 10/43] smbtorture: add test "open-brlock-deadlock" - -smbtorture reproducer for bug 15767. As it needs a very specific setup that -can't easily be done in selftest, the test is only executed when manually called -with - - --option=torture:open_brlock_deadlock_timemout=SEC - -To prepare the setup for the test set: - - tdb_hash_size:locking.tdb = 1 - tdb_hash_size:brlock.tdb = 1 - -and remove both tdb from disk which is needed so the TDBs get recreated with the -new hash_size. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 7c60498cee7dca5770d4d1f623c472d585ae9cae) ---- - source4/torture/smb2/lock.c | 283 ++++++++++++++++++++++++++++++++++++ - 1 file changed, 283 insertions(+) - -diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c -index eac0d557fc3..e5cf61a471a 100644 ---- a/source4/torture/smb2/lock.c -+++ b/source4/torture/smb2/lock.c -@@ -3465,6 +3465,288 @@ done: - return ret; - } - -+struct open_brlock_deadlock_state { -+ bool stop; -+ bool ok; -+ struct torture_context *tctx; -+ struct smb2_tree *tree1; -+ struct smb2_tree *tree2; -+ struct smb2_create cr; -+ struct smb2_request *cr_req; -+ struct smb2_close cl; -+ struct smb2_request *cl_req; -+ -+ struct smb2_lock_element el; -+ struct smb2_lock lock; -+ struct smb2_request *lock_req; -+}; -+ -+static void test_open_brlock_deadlock_loop_opened(struct smb2_request *req); -+ -+static void test_open_brlock_deadlock_loop_open( -+ struct open_brlock_deadlock_state *state) -+{ -+ if (state->stop) { -+ return; -+ } -+ -+ state->cr_req = smb2_create_send(state->tree1, &state->cr); -+ torture_assert_goto(state->tctx, state->cr_req != NULL, state->ok, failed, -+ "smb2_create_send failed\n"); -+ -+ state->cr_req->async.fn = test_open_brlock_deadlock_loop_opened; -+ state->cr_req->async.private_data = state; -+ return; -+failed: -+ state->stop = true; -+} -+ -+static void test_open_brlock_deadlock_loop_close( -+ struct open_brlock_deadlock_state *state); -+ -+static void test_open_brlock_deadlock_loop_opened(struct smb2_request *req) -+{ -+ struct open_brlock_deadlock_state *state = req->async.private_data; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ NTSTATUS status; -+ -+ status = smb2_create_recv(req, frame, &state->cr); -+ torture_assert_ntstatus_ok_goto(state->tctx, status, -+ state->ok, failed, __location__); -+ state->cr_req = NULL; -+ -+ TALLOC_FREE(frame); -+ test_open_brlock_deadlock_loop_close(state); -+ return; -+ -+failed: -+ state->stop = true; -+ TALLOC_FREE(frame); -+} -+ -+static void test_open_brlock_deadlock_loop_closed(struct smb2_request *req); -+ -+static void test_open_brlock_deadlock_loop_close( -+ struct open_brlock_deadlock_state *state) -+{ -+ if (state->stop) { -+ return; -+ } -+ -+ state->cl.in.file = state->cr.out.file; -+ state->cl_req = smb2_close_send(state->tree1, &state->cl); -+ torture_assert_goto(state->tctx, state->cl_req != NULL, state->ok, failed, -+ "smb2_create_send failed\n"); -+ -+ state->cl_req->async.fn = test_open_brlock_deadlock_loop_closed; -+ state->cl_req->async.private_data = state; -+ return; -+failed: -+ state->stop = true; -+} -+ -+static void test_open_brlock_deadlock_loop_closed(struct smb2_request *req) -+{ -+ struct open_brlock_deadlock_state *state = req->async.private_data; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ NTSTATUS status; -+ -+ status = smb2_close_recv(req, &state->cl); -+ torture_assert_ntstatus_ok_goto(state->tctx, status, -+ state->ok, failed, __location__); -+ state->cl_req = NULL; -+ -+ TALLOC_FREE(frame); -+ test_open_brlock_deadlock_loop_open(state); -+ return; -+ -+failed: -+ state->stop = true; -+ TALLOC_FREE(frame); -+} -+ -+static void test_open_brlock_deadlock_loop_locked(struct smb2_request *req); -+ -+static void test_open_brlock_deadlock_loop_lock( -+ struct open_brlock_deadlock_state *state) -+{ -+ if (state->stop) { -+ return; -+ } -+ -+ state->el.flags = SMB2_LOCK_FLAG_EXCLUSIVE; -+ -+ state->lock_req = smb2_lock_send(state->tree2, &state->lock); -+ torture_assert_goto(state->tctx, state->lock_req != NULL, -+ state->ok, failed, -+ "smb2_create_send failed\n"); -+ -+ state->lock_req->async.fn = test_open_brlock_deadlock_loop_locked; -+ state->lock_req->async.private_data = state; -+ return; -+failed: -+ state->stop = true; -+} -+ -+static void test_open_brlock_deadlock_loop_unlock( -+ struct open_brlock_deadlock_state *state); -+ -+static void test_open_brlock_deadlock_loop_locked(struct smb2_request *req) -+{ -+ struct open_brlock_deadlock_state *state = req->async.private_data; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ NTSTATUS status; -+ -+ status = smb2_lock_recv(req, &state->lock); -+ torture_assert_ntstatus_ok_goto(state->tctx, status, -+ state->ok, failed, __location__); -+ state->lock_req = NULL; -+ -+ TALLOC_FREE(frame); -+ test_open_brlock_deadlock_loop_unlock(state); -+ return; -+ -+failed: -+ state->stop = true; -+ TALLOC_FREE(frame); -+} -+ -+static void test_open_brlock_deadlock_loop_unlocked(struct smb2_request *req); -+ -+static void test_open_brlock_deadlock_loop_unlock( -+ struct open_brlock_deadlock_state *state) -+{ -+ if (state->stop) { -+ return; -+ } -+ -+ state->el.flags = SMB2_LOCK_FLAG_UNLOCK; -+ -+ state->lock_req = smb2_lock_send(state->tree2, &state->lock); -+ torture_assert_goto(state->tctx, state->lock_req != NULL, -+ state->ok, failed, -+ "smb2_create_send failed\n"); -+ -+ state->lock_req->async.fn = test_open_brlock_deadlock_loop_unlocked; -+ state->lock_req->async.private_data = state; -+ return; -+failed: -+ state->stop = true; -+} -+ -+static void test_open_brlock_deadlock_loop_unlocked(struct smb2_request *req) -+{ -+ struct open_brlock_deadlock_state *state = req->async.private_data; -+ TALLOC_CTX *frame = talloc_stackframe(); -+ NTSTATUS status; -+ -+ status = smb2_lock_recv(req, &state->lock); -+ torture_assert_ntstatus_ok_goto(state->tctx, status, -+ state->ok, failed, __location__); -+ state->lock_req = NULL; -+ -+ TALLOC_FREE(frame); -+ test_open_brlock_deadlock_loop_lock(state); -+ return; -+ -+failed: -+ state->stop = true; -+ TALLOC_FREE(frame); -+} -+ -+ -+static void test_open_brlock_deadlock_timeout(struct tevent_context *ev, -+ struct tevent_timer *te, -+ struct timeval current_time, -+ void *private_data) -+{ -+ struct open_brlock_deadlock_state *state = private_data; -+ state->stop = true; -+} -+ -+static bool test_open_brlock_deadlock(struct torture_context *tctx, -+ struct smb2_tree *tree1, -+ struct smb2_tree *tree2) -+{ -+ int timeout_sec = torture_setting_int(tctx, "open_brlock_deadlock_timemout", 0); -+ const char *fname1 = BASEDIR "\\test_open_brlock_deadlock1.txt"; -+ const char *fname2 = BASEDIR "\\test_open_brlock_deadlock2.txt"; -+ struct open_brlock_deadlock_state state; -+ struct smb2_handle h = {}; -+ uint8_t buf[200]; -+ struct tevent_timer *te = NULL; -+ NTSTATUS status; -+ bool ret = true; -+ -+ if (timeout_sec == 0) { -+ torture_skip_goto(tctx, done, "Test skipped, pass '--option=torture:open_brlock_deadlock_timemout=SEC' to run\n"); -+ } -+ -+ state = (struct open_brlock_deadlock_state) { -+ .tctx = tctx, -+ .tree1 = tree1, -+ .tree2 = tree2, -+ }; -+ -+ ret = smb2_util_setup_dir(tctx, tree1, BASEDIR); -+ torture_assert_goto(tctx, ret, ret, done, -+ "smb2_util_setup_dir failed"); -+ -+ status = torture_smb2_testfile(tree1, fname1, &h); -+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, -+ "torture_smb2_testfile failed"); -+ status = smb2_util_close(tree1, h); -+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, -+ "smb2_util_close failed"); -+ -+ status = torture_smb2_testfile(tree2, fname2, &h); -+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, -+ "torture_smb2_testfile failed"); -+ -+ status = smb2_util_write(tree2, h, buf, 0, ARRAY_SIZE(buf)); -+ torture_assert_ntstatus_ok_goto(tctx, status, ret, done, -+ "smb2_util_write failed"); -+ -+ state.cr = (struct smb2_create) { -+ .in.desired_access = SEC_FILE_READ_DATA, -+ .in.share_access = NTCREATEX_SHARE_ACCESS_MASK, -+ .in.create_disposition = NTCREATEX_DISP_OPEN, -+ .in.fname = fname1, -+ }; -+ -+ state.el = (struct smb2_lock_element) { -+ .length = 1, -+ .offset = 0, -+ }; -+ state.lock = (struct smb2_lock) { -+ .in.locks = &state.el, -+ .in.lock_count = 1, -+ .in.file.handle = h, -+ }; -+ -+ te = tevent_add_timer(tctx->ev, -+ tctx, -+ timeval_current_ofs(timeout_sec, 0), -+ test_open_brlock_deadlock_timeout, -+ &state); -+ torture_assert_goto(tctx, te != NULL, ret, done, __location__); -+ -+ test_open_brlock_deadlock_loop_open(&state); -+ test_open_brlock_deadlock_loop_lock(&state); -+ -+ while (!state.stop) { -+ int rc = tevent_loop_once(tctx->ev); -+ torture_assert_int_equal(tctx, rc, 0, "tevent_loop_once"); -+ } -+ -+done: -+ if (!smb2_util_handle_empty(h)) { -+ smb2_util_close(tree2, h); -+ } -+ smb2_deltree(tree1, BASEDIR); -+ return ret; -+} -+ - /* basic testing of SMB2 locking - */ - struct torture_suite *torture_smb2_lock_init(TALLOC_CTX *ctx) -@@ -3506,6 +3788,7 @@ struct torture_suite *torture_smb2_lock_init(TALLOC_CTX *ctx) - torture_suite_add_1smb2_test(suite, "replay_smb3_specification_multi", - test_replay_smb3_specification_multi); - torture_suite_add_1smb2_test(suite, "ctdb-delrec-deadlock", test_deadlock); -+ torture_suite_add_2smb2_test(suite, "open-brlock-deadlock", test_open_brlock_deadlock); - - suite->description = talloc_strdup(suite, "SMB2-LOCK tests"); - --- -2.51.0 - - -From fe9563bc0140fbbb2aa5a6342a1948984c59043a Mon Sep 17 00:00:00 2001 -From: Stefan Metzmacher -Date: Mon, 6 Jan 2025 15:59:27 +0100 -Subject: [PATCH 11/43] s3/brlock: split out brl_get_locks_readonly_parse() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Pair-Programmed-With: Ralph Boehme -Signed-off-by: Ralph Boehme -Signed-off-by: Stefan Metzmacher -(cherry picked from commit 94e7cbcc32b73e4d56e7209e04d22d4270a6eb5b) ---- - source3/locking/brlock.c | 43 ++++++++++++++++++++++++++-------------- - 1 file changed, 28 insertions(+), 15 deletions(-) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index b0295174954..c75b83c048d 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -1768,29 +1768,18 @@ static void brl_get_locks_readonly_parser(TDB_DATA key, TDB_DATA data, - *state->br_lock = br_lck; - } - --struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) -+static struct byte_range_lock *brl_get_locks_readonly_parse(TALLOC_CTX *mem_ctx, -+ files_struct *fsp) - { - struct byte_range_lock *br_lock = NULL; - struct brl_get_locks_readonly_state state; - NTSTATUS status; - -- DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n", -- dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum)); -- -- if ((fsp->brlock_rec != NULL) -- && (dbwrap_get_seqnum(brlock_db) == fsp->brlock_seqnum)) { -- /* -- * We have cached the brlock_rec and the database did not -- * change. -- */ -- return fsp->brlock_rec; -- } -- - /* - * Parse the record fresh from the database - */ - -- state.mem_ctx = fsp; -+ state.mem_ctx = mem_ctx; - state.br_lock = &br_lock; - - status = dbwrap_parse_record( -@@ -1803,7 +1792,7 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) - /* - * No locks on this file. Return an empty br_lock. - */ -- br_lock = talloc_zero(fsp, struct byte_range_lock); -+ br_lock = talloc_zero(mem_ctx, struct byte_range_lock); - if (br_lock == NULL) { - return NULL; - } -@@ -1821,6 +1810,30 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) - br_lock->modified = false; - br_lock->record = NULL; - -+ return br_lock; -+} -+ -+struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp) -+{ -+ struct byte_range_lock *br_lock = NULL; -+ -+ DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n", -+ dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum)); -+ -+ if ((fsp->brlock_rec != NULL) -+ && (dbwrap_get_seqnum(brlock_db) == fsp->brlock_seqnum)) { -+ /* -+ * We have cached the brlock_rec and the database did not -+ * change. -+ */ -+ return fsp->brlock_rec; -+ } -+ -+ br_lock = brl_get_locks_readonly_parse(fsp, fsp); -+ if (br_lock == NULL) { -+ return NULL; -+ } -+ - /* - * Cache the brlock struct, invalidated when the dbwrap_seqnum - * changes. See beginning of this routine. --- -2.51.0 - - -From 2c3e6fed2b1fc6e854293446ed74b9e98900815e Mon Sep 17 00:00:00 2001 -From: Stefan Metzmacher -Date: Mon, 6 Jan 2025 17:07:11 +0100 -Subject: [PATCH 12/43] s3/brlock: add brl_req_set() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Stefan Metzmacher -Reviewed-by: Ralph Boehme -(cherry picked from commit c9c04c7d75dee0c3e6e843b581624a3852042057) ---- - source3/locking/brlock.c | 9 +++++++++ - source3/locking/proto.h | 3 +++ - 2 files changed, 12 insertions(+) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index c75b83c048d..51d9dc2e599 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -84,6 +84,15 @@ struct files_struct *brl_fsp(struct byte_range_lock *brl) - return brl->fsp; - } - -+ -+void brl_req_set(struct byte_range_lock *br_lck, -+ TALLOC_CTX *req_mem_ctx, -+ const struct GUID *req_guid) -+{ -+ br_lck->req_mem_ctx = req_mem_ctx; -+ br_lck->req_guid = req_guid; -+} -+ - TALLOC_CTX *brl_req_mem_ctx(const struct byte_range_lock *brl) - { - if (brl->req_mem_ctx == NULL) { -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index 7fc177d7aa6..3413596baed 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -32,6 +32,9 @@ 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); -+void brl_req_set(struct byte_range_lock *br_lck, -+ TALLOC_CTX *req_mem_ctx, -+ const struct GUID *req_guid); - TALLOC_CTX *brl_req_mem_ctx(const struct byte_range_lock *brl); - const struct GUID *brl_req_guid(const struct byte_range_lock *brl); - --- -2.51.0 - - -From 1a3c7565c112ba2bf6342c93f74b1888fb1dcdfc Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Sat, 1 Feb 2025 10:37:40 +0100 -Subject: [PATCH 13/43] s3/brlock: add share_mode_do_locked_brl() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Pair-Programmed-With: Stefan Metzmacher -Signed-off-by: Ralph Boehme -Signed-off-by: Stefan Metzmacher -(cherry picked from commit e17fb732c89f8b34de00904383044de3c4f85bd0) ---- - source3/locking/brlock.c | 103 +++++++++++++++++++++++++++++++++++++++ - source3/locking/proto.h | 8 +++ - 2 files changed, 111 insertions(+) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index 51d9dc2e599..fcbce52f9c1 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -34,6 +34,7 @@ - #include "serverid.h" - #include "messages.h" - #include "util_tdb.h" -+#include "source3/locking/share_mode_lock.h" - - #undef DBGC_CLASS - #define DBGC_CLASS DBGC_LOCKING -@@ -1927,3 +1928,105 @@ done: - talloc_free(frame); - return ret; - } -+ -+struct share_mode_do_locked_brl_state { -+ share_mode_do_locked_brl_fn_t cb; -+ void *cb_data; -+ struct files_struct *fsp; -+ NTSTATUS status; -+}; -+ -+static void share_mode_do_locked_brl_fn(struct share_mode_lock *lck, -+ void *private_data) -+{ -+ struct share_mode_do_locked_brl_state *state = private_data; -+ struct byte_range_lock *br_lck = NULL; -+ TDB_DATA key = make_tdb_data((uint8_t *)&state->fsp->file_id, -+ sizeof(state->fsp->file_id)); -+ -+ if (lp_locking(state->fsp->conn->params) && -+ state->fsp->fsp_flags.can_lock) -+ { -+ br_lck = brl_get_locks_readonly_parse(talloc_tos(), -+ state->fsp); -+ if (br_lck == NULL) { -+ state->status = NT_STATUS_NO_MEMORY; -+ return; -+ } -+ } -+ -+ state->cb(lck, br_lck, state->cb_data); -+ -+ if (br_lck == NULL || !br_lck->modified) { -+ TALLOC_FREE(br_lck); -+ return; -+ } -+ -+ br_lck->record = dbwrap_fetch_locked(brlock_db, br_lck, key); -+ if (br_lck->record == NULL) { -+ DBG_ERR("Could not lock byte range lock entry for '%s'\n", -+ fsp_str_dbg(state->fsp)); -+ TALLOC_FREE(br_lck); -+ state->status = NT_STATUS_INTERNAL_DB_ERROR; -+ return; -+ } -+ -+ byte_range_lock_flush(br_lck); -+ share_mode_wakeup_waiters(br_lck->fsp->file_id); -+ TALLOC_FREE(br_lck); -+} -+ -+/* -+ * Run cb with a glock'ed locking.tdb record, providing both a share_mode_lock -+ * and a br_lck object. An initial read-only, but upgradable, br_lck object is -+ * fetched from brlock.tdb while holding the glock on the locking.tdb record. -+ * -+ * This function only ever hold one low-level TDB chainlock at a time on either -+ * locking.tdb or brlock.tdb, so it can't run afoul any lock order violations. -+ * -+ * Note that br_lck argument in the callback might be NULL in case lp_locking() -+ * is disabled, the fsp doesn't allow locking or is a directory, so either -+ * the caller or the callback have to check for this. -+ */ -+NTSTATUS share_mode_do_locked_brl(files_struct *fsp, -+ share_mode_do_locked_brl_fn_t cb, -+ void *cb_data) -+{ -+ static bool recursion_guard; -+ TALLOC_CTX *frame = NULL; -+ struct share_mode_do_locked_brl_state state = { -+ .fsp = fsp, -+ .cb = cb, -+ .cb_data = cb_data, -+ }; -+ NTSTATUS status; -+ -+ SMB_ASSERT(!recursion_guard); -+ -+ /* silently return ok on print files as we don't do locking there */ -+ if (fsp->print_file) { -+ return NT_STATUS_OK; -+ } -+ -+ frame = talloc_stackframe(); -+ -+ recursion_guard = true; -+ status = share_mode_do_locked_vfs_allowed( -+ fsp->file_id, -+ share_mode_do_locked_brl_fn, -+ &state); -+ recursion_guard = false; -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("share_mode_do_locked_vfs_allowed() failed for %s - %s\n", -+ fsp_str_dbg(fsp), nt_errstr(status)); -+ TALLOC_FREE(frame); -+ return status; -+ } -+ if (!NT_STATUS_IS_OK(state.status)) { -+ TALLOC_FREE(frame); -+ return state.status; -+ } -+ -+ TALLOC_FREE(frame); -+ return NT_STATUS_OK; -+} -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index 3413596baed..c9d769ba53f 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -87,6 +87,14 @@ 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 share_mode_lock; -+typedef void (*share_mode_do_locked_brl_fn_t)( -+ struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, /* br_lck can be NULL */ -+ void *private_data); -+NTSTATUS share_mode_do_locked_brl(files_struct *fsp, -+ share_mode_do_locked_brl_fn_t fn, -+ void *private_data); - 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); --- -2.51.0 - - -From f29fdf9d8da34db5b129f2ccd00a597dcfe68e55 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Wed, 8 Jan 2025 15:43:04 +0100 -Subject: [PATCH 14/43] s3/brlock: don't increment current_lock_count if - do_lock_fn() failed - -Also only assign psmblctx and pblocker_pid if the lock request failed. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 3a0c6e99de4377f44bc29766b6ceb79040caed9f) ---- - source3/locking/locking.c | 20 +++++++++++--------- - 1 file changed, 11 insertions(+), 9 deletions(-) - -diff --git a/source3/locking/locking.c b/source3/locking/locking.c -index 41b54b14c6b..ea692711627 100644 ---- a/source3/locking/locking.c -+++ b/source3/locking/locking.c -@@ -344,19 +344,21 @@ NTSTATUS do_lock(files_struct *fsp, - nt_errstr(status)); - return status; - } -- -- if (psmblctx != NULL) { -- *psmblctx = state.blocker_smblctx; -- } -- if (pblocker_pid != NULL) { -- *pblocker_pid = state.blocker_pid; -+ if (!NT_STATUS_IS_OK(state.status)) { -+ DBG_DEBUG("do_lock_fn returned %s\n", -+ nt_errstr(state.status)); -+ if (psmblctx != NULL) { -+ *psmblctx = state.blocker_smblctx; -+ } -+ if (pblocker_pid != NULL) { -+ *pblocker_pid = state.blocker_pid; -+ } -+ return state.status; - } - -- DBG_DEBUG("returning status=%s\n", nt_errstr(state.status)); -- - increment_current_lock_count(fsp, lock_flav); - -- return state.status; -+ return NT_STATUS_OK; - } - - /**************************************************************************** --- -2.51.0 - - -From 68a48f73a8987db27d80d13f2871fd9c057df196 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Wed, 29 Jan 2025 06:13:29 +0100 -Subject: [PATCH 15/43] s3/locking: add brl_set_modified() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 2772f147c9b13cd2160181c4f7905b54ab765054) ---- - source3/locking/brlock.c | 5 +++++ - source3/locking/proto.h | 1 + - 2 files changed, 6 insertions(+) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index fcbce52f9c1..0e58339b108 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -2030,3 +2030,8 @@ NTSTATUS share_mode_do_locked_brl(files_struct *fsp, - TALLOC_FREE(frame); - return NT_STATUS_OK; - } -+ -+void brl_set_modified(struct byte_range_lock *br_lck, bool modified) -+{ -+ br_lck->modified = modified; -+} -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index c9d769ba53f..c74539c8161 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -99,6 +99,7 @@ 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); - bool brl_cleanup_disconnected(struct file_id fid, uint64_t open_persistent_id); -+void brl_set_modified(struct byte_range_lock *br_lck, bool modified); - - /* The following definitions come from locking/locking.c */ - --- -2.51.0 - - -From 4888165536438d742e46be57087dbc2b29bd190c Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Wed, 29 Jan 2025 06:13:44 +0100 -Subject: [PATCH 16/43] smbd: use share_mode_do_locked_brl() - -Fix a deadlock that can happen if two clients happen to open and byte-range-lock -two different files whos record in locking.tdb and brlock.tdb happen to sit on -the same hashchain. - -The deadlock was introduced by commit -680c7907325b433856ac1dd916ab63e671fbe4ab. Before, we used share_mode_do_locked() -in do_lock() which meant we acquired a chainlock on locking.tdb before getting a -chainlock on brlock.tdb via brl_get_locks_for_locking(), so the TDB chainlock -order invariant was always uphold. - -The following race between specific client requests lead to the deadlock. - -Client A) issues a byte-range-lock request on a file: - -A1) glock locking.tdb (via _share_mode_do_locked_vfs_allowed()) -A2) chainlock brlock.tdb (via brl_lock()) -A3) attempt to chainlock locking.tdb (via share_mode_g_lock_dump()) -[1] - -Client B) opens a different (!) file: - -B1) glock and chainlock locking.tdb (via _share_mode_entry_prepare_lock()) -B2) attempt to chainlock brlock.tdb (via file_has_brlocks()) -[2] - -The glock from A1 is per record and hence doesn't synchronize with the glock -from B1 as it is for a different file and hence a different record, subsequently -A2 and A3 violate the lock order constraint - -To avoid the chainlock lock order violation in the second client we modify the -br-lock code to not take the brlock.tdb chainlock from step A2 via -br_get_locks() for the whole time we process the request. Instead we just fetch -the br-locks via br_get_locks_readonly(), so when running into -contend_level2_oplocks_begin_default() to check for leases and looking into -locking.tdb we don't hold a brlock.tdb chainlock. - -Or im simpler terms, we only ever take at most one low-level TDB chainlock at a -time: - -Byte-range-lock code calls share_mode_do_locked_brl(..., cb_fn, ...): -1) chainlock locking.tdb -2) glock locking.tdb (via share_mode_do_locked_vfs_allowed()) -3) chainunlock locking.tdb -4) share_mode_do_locked_brl_fn() -> brl_get_locks_readonly_parse(): - a) chainlock brlock.tdb - b) parse record and store in-memory copy - c) chainunlock brlock.tdb -5) run cb_fn() -6) chainlock brlock.tdb: - a) br_lck->record = dbwrap_fetch_locked(brlock_db, ...) - b) store modifed br_lck from 5) via byte_range_lock_flush() -7) chainunlock brlock.tdb -8) chainlock locking.tdb -9) gunlock locking.tdb -10) chainunlock locking.tdb - -All access to brlock.tdb is synchronized correctly via glocks on the locking.tdb -record of the file (step 3)), so operations still appear atomic to clients. - -As a result of using share_mode_do_locked_brl(), the functions do_[un]lock() -> -brl_[un]lock() now loop over the same br_lck object in memory, avoiding -repeatedly fetching and storing the locks per loop. - -[1] -Full SBT: - - #0 0x00007fffa0cecbb0 in __pthread_mutex_lock_full () from /lib64/glibc-hwcaps/power9/libpthread-2.28.so - #1 0x00007fffa0a73cf8 in chain_mutex_lock (m=, m@entry=0x7fff9ae071b0, waitflag=, waitflag@entry=true) at ../../lib/tdb/common/mutex.c:182 - #2 0x00007fffa0a7432c in tdb_mutex_lock (tdb=0x1543ba120, rw=, off=, len=, waitflag=, pret=0x7fffd7df3858) at ../../lib/tdb/common/mutex.c:234 - #3 0x00007fffa0a6812c in fcntl_lock (waitflag=, len=1, off=376608, rw=0, tdb=0x1543ba120) at ../../lib/tdb/common/lock.c:200 - #4 tdb_brlock (tdb=0x1543ba120, rw_type=, offset=, len=1, flags=) at ../../lib/tdb/common/lock.c:200 - #5 0x00007fffa0a68af8 in tdb_nest_lock (flags=, ltype=0, offset=, tdb=0x1543ba120) at ../../lib/tdb/common/lock.c:390 - #6 tdb_nest_lock (tdb=0x1543ba120, offset=, ltype=, flags=) at ../../lib/tdb/common/lock.c:336 - #7 0x00007fffa0a69088 in tdb_lock_list (tdb=0x1543ba120, list=, ltype=, waitflag=) at ../../lib/tdb/common/lock.c:482 - #8 0x00007fffa0a69198 in tdb_lock (tdb=0x1543ba120, list=, ltype=) at ../../lib/tdb/common/lock.c:500 - #9 0x00007fffa0a64b50 in tdb_find_lock_hash (tdb=, tdb@entry=0x1543ba120, key=..., hash=, locktype=, locktype@entry=0, rec=, rec@entry=0x7fffd7df3ab0) at ../../lib/tdb/common/tdb.c:165 - #10 0x00007fffa0a64ed0 in tdb_parse_record (tdb=0x1543ba120, key=..., parser=0x7fffa0e74470 , private_data=0x7fffd7df3b18) at ../../lib/tdb/common/tdb.c:329 - #11 0x00007fffa0e74cbc in db_ctdb_ltdb_parse (db=, private_data=0x7fffd7df3b70, parser=0x7fffa0e76470 , key=...) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:170 - #12 db_ctdb_try_parse_local_record (ctx=ctx@entry=0x1543d4580, key=..., state=state@entry=0x7fffd7df3b70) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1385 - #13 0x00007fffa0e76024 in db_ctdb_parse_record (db=, key=..., parser=0x7fffa1313910 , private_data=0x7fffd7df3c08) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1425 - #14 0x00007fffa0884760 in dbwrap_parse_record (db=, key=..., parser=, private_data=) at ../../lib/dbwrap/dbwrap.c:454 - #15 0x00007fffa1313ab4 in dbwrap_watched_parse_record (db=0x1543a7160, key=..., parser=0x7fffa13187d0 , private_data=0x7fffd7df3ce8) at ../../source3/lib/dbwrap/dbwrap_watch.c:783 - #16 0x00007fffa0884760 in dbwrap_parse_record (db=, key=..., parser=, private_data=) at ../../lib/dbwrap/dbwrap.c:454 - #17 0x00007fffa131c004 in g_lock_dump (ctx=, key=..., fn=0x7fffa14f3d70 , private_data=0x7fffd7df3dd8) at ../../source3/lib/g_lock.c:1653 - #18 0x00007fffa14f434c in share_mode_g_lock_dump (key=..., fn=0x7fffa14f3d70 , private_data=0x7fffd7df3dd8) at ../../source3/locking/share_mode_lock.c:96 - #19 0x00007fffa14f8d44 in fsp_update_share_mode_flags (fsp=0x15433c550) at ../../source3/locking/share_mode_lock.c:1181 - #20 file_has_read_lease (fsp=0x15433c550) at ../../source3/locking/share_mode_lock.c:1207 - #21 0x00007fffa15ccc98 in contend_level2_oplocks_begin_default (type=, fsp=0x15433c550) at ../../source3/smbd/smb2_oplock.c:1282 - #22 smbd_contend_level2_oplocks_begin (fsp=0x15433c550, type=) at ../../source3/smbd/smb2_oplock.c:1338 - #23 0x00007fffa0dd0b54 in contend_level2_oplocks_begin (fsp=, type=) at ../../source3/lib/smbd_shim.c:72 - #24 0x00007fffa14ecfd0 in brl_lock_windows_default (br_lck=0x154421330, plock=0x7fffd7df4250) at ../../source3/locking/brlock.c:457 - #25 0x00007fffa150b70c in vfswrap_brl_lock_windows (handle=, br_lck=, plock=) at ../../source3/modules/vfs_default.c:3424 - #26 0x00007fffa1561910 in smb_vfs_call_brl_lock_windows (handle=, br_lck=, plock=) at ../../source3/smbd/vfs.c:2686 - #27 0x00007fff9c0a7350 in smb_time_audit_brl_lock_windows (handle=, br_lck=0x154421330, plock=0x7fffd7df4250) at ../../source3/modules/vfs_time_audit.c:1740 - #28 0x00007fffa1561910 in smb_vfs_call_brl_lock_windows (handle=, br_lck=, plock=) at ../../source3/smbd/vfs.c:2686 - #29 0x00007fffa14ed410 in brl_lock (br_lck=0x154421330, smblctx=3102281601, pid=..., start=0, size=18446744073709551615, lock_type=, lock_flav=WINDOWS_LOCK, blocker_pid=0x7fffd7df4540, psmblctx=0x7fffd7df4558) at ../../source3/locking/brlock.c:1004 - #30 0x00007fffa14e7b18 in do_lock_fn (lck=, private_data=0x7fffd7df4508) at ../../source3/locking/locking.c:271 - #31 0x00007fffa14fcd94 in _share_mode_do_locked_vfs_allowed (id=..., fn=0x7fffa14e7a60 , private_data=0x7fffd7df4508, location=) at ../../source3/locking/share_mode_lock.c:2927 - #32 0x00007fffa14e918c in do_lock (fsp=0x15433c550, req_mem_ctx=, req_guid=, smblctx=, count=18446744073709551615, offset=0, lock_type=, lock_flav=, pblocker_pid=0x7fffd7df46f0, - psmblctx=0x7fffd7df46d8) at ../../source3/locking/locking.c:335 - #33 0x00007fffa155381c in smbd_do_locks_try (fsp=0x15433c550, num_locks=, locks=0x1543bc310, blocker_idx=0x7fffd7df46d6, blocking_pid=0x7fffd7df46f0, blocking_smblctx=0x7fffd7df46d8) at ../../source3/smbd/blocking.c:46 - #34 0x00007fffa159dc90 in smbd_smb2_lock_try (req=req@entry=0x1543bc080) at ../../source3/smbd/smb2_lock.c:590 - #35 0x00007fffa159ee8c in smbd_smb2_lock_send (in_locks=, in_lock_count=1, in_lock_sequence=, fsp=0x15433c550, smb2req=0x1543532e0, ev=0x154328120, mem_ctx=0x1543532e0) at ../../source3/smbd/smb2_lock.c:488 - #36 smbd_smb2_request_process_lock (req=0x1543532e0) at ../../source3/smbd/smb2_lock.c:150 - #37 0x00007fffa158a368 in smbd_smb2_request_dispatch (req=0x1543532e0) at ../../source3/smbd/smb2_server.c:3515 - #38 0x00007fffa158c540 in smbd_smb2_io_handler (fde_flags=, xconn=0x154313f30) at ../../source3/smbd/smb2_server.c:5112 - #39 smbd_smb2_connection_handler (ev=, fde=, flags=, private_data=) at ../../source3/smbd/smb2_server.c:5150 - #40 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543670f0, flags=, removed=0x0) at ../../lib/tevent/tevent_fd.c:158 - #41 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4b28, epoll_ev=0x1543b4e80) at ../../lib/tevent/tevent_epoll.c:730 - #42 epoll_event_loop_once (ev=, location=) at ../../lib/tevent/tevent_epoll.c:946 - #43 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:110 - #44 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent.c:823 - #45 0x00007fffa1197884 in tevent_common_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:950 - #46 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:141 - #47 0x00007fffa1197978 in _tevent_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:971 - #48 0x00007fffa15737fc in smbd_process (ev_ctx=0x154328120, msg_ctx=, sock_fd=, interactive=) at ../../source3/smbd/smb2_process.c:2158 - #49 0x000000011db5c554 in smbd_accept_connection (ev=0x154328120, fde=, flags=, private_data=) at ../../source3/smbd/server.c:1150 - #50 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543ac2d0, flags=, removed=0x0) at ../../lib/tevent/tevent_fd.c:158 - #51 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4f98, epoll_ev=0x154328350) at ../../lib/tevent/tevent_epoll.c:730 - #52 epoll_event_loop_once (ev=, location=) at ../../lib/tevent/tevent_epoll.c:946 - #53 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:110 - #54 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent.c:823 - #55 0x00007fffa1197884 in tevent_common_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:950 - #56 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:141 - #57 0x00007fffa1197978 in _tevent_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:971 - #58 0x000000011db58c54 in smbd_parent_loop (parent=, ev_ctx=0x154328120) at ../../source3/smbd/server.c:1499 - #59 main (argc=, argv=) at ../../source3/smbd/server.c:2258 - -[2] -Full SBT: - - #0 0x00007fffa0cecbb0 in __pthread_mutex_lock_full () from /lib64/glibc-hwcaps/power9/libpthread-2.28.so - #1 0x00007fffa0a73cf8 in chain_mutex_lock (m=, m@entry=0x7fff9b3a71b0, waitflag=, waitflag@entry=true) at ../../lib/tdb/common/mutex.c:182 - #2 0x00007fffa0a7432c in tdb_mutex_lock (tdb=0x1543c6900, rw=, off=, len=, waitflag=, pret=0x7fffd7df2e28) at ../../lib/tdb/common/mutex.c:234 - #3 0x00007fffa0a6812c in fcntl_lock (waitflag=, len=1, off=376608, rw=0, tdb=0x1543c6900) at ../../lib/tdb/common/lock.c:200 - #4 tdb_brlock (tdb=0x1543c6900, rw_type=, offset=, len=1, flags=) at ../../lib/tdb/common/lock.c:200 - #5 0x00007fffa0a68af8 in tdb_nest_lock (flags=, ltype=0, offset=, tdb=0x1543c6900) at ../../lib/tdb/common/lock.c:390 - #6 tdb_nest_lock (tdb=0x1543c6900, offset=, ltype=, flags=) at ../../lib/tdb/common/lock.c:336 - #7 0x00007fffa0a69088 in tdb_lock_list (tdb=0x1543c6900, list=, ltype=, waitflag=) at ../../lib/tdb/common/lock.c:482 - #8 0x00007fffa0a69198 in tdb_lock (tdb=0x1543c6900, list=, ltype=) at ../../lib/tdb/common/lock.c:500 - #9 0x00007fffa0a64b50 in tdb_find_lock_hash (tdb=, tdb@entry=0x1543c6900, key=..., hash=, locktype=, locktype@entry=0, rec=, rec@entry=0x7fffd7df3080) at ../../lib/tdb/common/tdb.c:165 - #10 0x00007fffa0a64ed0 in tdb_parse_record (tdb=0x1543c6900, key=..., parser=0x7fffa0e74470 , private_data=0x7fffd7df30e8) at ../../lib/tdb/common/tdb.c:329 - #11 0x00007fffa0e74cbc in db_ctdb_ltdb_parse (db=, private_data=0x7fffd7df3140, parser=0x7fffa0e76470 , key=...) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:170 - #12 db_ctdb_try_parse_local_record (ctx=ctx@entry=0x154328fc0, key=..., state=state@entry=0x7fffd7df3140) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1385 - #13 0x00007fffa0e76024 in db_ctdb_parse_record (db=, key=..., parser=0x7fffa14ec820 , private_data=0x7fffd7df3218) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1425 - #14 0x00007fffa0884760 in dbwrap_parse_record (db=, key=..., parser=, private_data=) at ../../lib/dbwrap/dbwrap.c:454 - #15 0x00007fffa14ef5bc in brl_get_locks_readonly (fsp=0x1543d01e0) at ../../source3/locking/brlock.c:1884 - #16 0x00007fffa1546968 in file_has_brlocks (fsp=0x1543d01e0) at ../../source3/smbd/open.c:2232 - #17 delay_for_oplock (pgranted=, poplock_type=, first_open_attempt=, create_disposition=1, have_sharing_violation=false, lck=0x7fffd7df3ce8, lease=0x0, oplock_request=0, fsp=0x1543d01e0) at ../../source3/smbd/open.c:2749 - #18 handle_share_mode_lease (pgranted=, poplock_type=, first_open_attempt=, lease=0x0, oplock_request=0, share_access=7, access_mask=131201, create_disposition=1, lck=0x7fffd7df3ce8, fsp=0x1543d01e0) at ../../source3/smbd/open.c:2865 - #19 check_and_store_share_mode (first_open_attempt=, lease=0x0, oplock_request=0, share_access=7, access_mask=131201, create_disposition=1, lck=0x7fffd7df3ce8, req=0x154414800, fsp=0x1543d01e0) at ../../source3/smbd/open.c:3333 - #20 open_ntcreate_lock_add_entry (lck=0x7fffd7df3ce8, keep_locked=0x7fffd7df3ad0, private_data=0x7fffd7df3cc8) at ../../source3/smbd/open.c:3688 - #21 0x00007fffa14f6248 in share_mode_entry_prepare_lock_fn (glck=0x7fffd7df35b8, cb_private=0x7fffd7df3a88) at ../../source3/locking/share_mode_lock.c:2978 - #22 0x00007fffa1317680 in g_lock_lock_cb_run_and_store (cb_state=cb_state@entry=0x7fffd7df35b8) at ../../source3/lib/g_lock.c:597 - #23 0x00007fffa1319df8 in g_lock_lock_simple_fn (rec=0x7fffd7df3798, value=..., private_data=0x7fffd7df39a0) at ../../source3/lib/g_lock.c:1212 - #24 0x00007fffa13160e0 in dbwrap_watched_do_locked_fn (backend_rec=, backend_value=..., private_data=0x7fffd7df3768) at ../../source3/lib/dbwrap/dbwrap_watch.c:458 - #25 0x00007fffa0884e48 in dbwrap_do_locked (db=, key=..., fn=0x7fffa1316080 , private_data=0x7fffd7df3768) at ../../lib/dbwrap/dbwrap.c:602 - #26 0x00007fffa1315274 in dbwrap_watched_do_locked (db=0x1543a7160, key=..., fn=0x7fffa1319ca0 , private_data=0x7fffd7df39a0) at ../../source3/lib/dbwrap/dbwrap_watch.c:480 - #27 0x00007fffa0884d60 in dbwrap_do_locked (db=, key=..., fn=, private_data=) at ../../lib/dbwrap/dbwrap.c:582 - #28 0x00007fffa131b458 in g_lock_lock (ctx=0x1543cc630, key=..., type=, timeout=..., cb_fn=0x7fffa14f6190 , cb_private=0x7fffd7df3a88) at ../../source3/lib/g_lock.c:1267 - #29 0x00007fffa14fd060 in _share_mode_entry_prepare_lock (prepare_state=0x7fffd7df3cc8, id=..., servicepath=, smb_fname=, old_write_time=, fn=, private_data=0x7fffd7df3cc8, location=0x7fffa165b880 "../../source3/smbd/open.c:4292") at ../../source3/locking/share_mode_lock.c:3033 - #30 0x00007fffa15491e0 in open_file_ntcreate (conn=conn@entry=0x154382050, req=req@entry=0x154414800, access_mask=, access_mask@entry=131201, share_access=share_access@entry=7, create_disposition=create_disposition@entry=1, create_options=create_options@entry=0, new_dos_attributes=, new_dos_attributes@entry=128, oplock_request=oplock_request@entry=0, lease=, lease@entry=0x0, private_flags=, private_flags@entry=0, parent_dir_fname=, smb_fname_atname=, pinfo=, pinfo@entry=0x7fffd7df3f1c, fsp=, fsp@entry=0x1543d01e0) at ../../source3/smbd/open.c:4286 - #31 0x00007fffa154b94c in create_file_unixpath (conn=conn@entry=0x154382050, req=req@entry=0x154414800, dirfsp=dirfsp@entry=0x15439a7f0, smb_fname=smb_fname@entry=0x154416300, access_mask=access_mask@entry=131201, share_access=share_access@entry=7, create_disposition=create_disposition@entry=1, create_options=create_options@entry=0, file_attributes=file_attributes@entry=128, oplock_request=, oplock_request@entry=0, lease=, lease@entry=0x0, allocation_size=allocation_size@entry=0, private_flags=private_flags@entry=0, sd=sd@entry=0x0, ea_list=ea_list@entry=0x0, result=result@entry=0x7fffd7df4168, pinfo=pinfo@entry=0x7fffd7df4160) at ../../source3/smbd/open.c:6290 - #32 0x00007fffa154dfac in create_file_default (conn=0x154382050, req=0x154414800, dirfsp=0x15439a7f0, smb_fname=0x154416300, access_mask=, share_access=, create_disposition=, create_options=, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/open.c:6609 - #33 0x00007fffa150972c in vfswrap_create_file (handle=, req=, dirfsp=, smb_fname=, access_mask=, share_access=, create_disposition=, create_options=, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/modules/vfs_default.c:776 - #34 0x00007fffa1559cbc in smb_vfs_call_create_file (handle=, req=, dirfsp=, smb_fname=, access_mask=, share_access=, create_disposition=, create_options=, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/vfs.c:1560 - #35 0x00007fff9c0a9ec4 in smb_time_audit_create_file (handle=0x154426820, req=0x154414800, dirfsp=0x15439a7f0, fname=0x154416300, access_mask=, share_access=, create_disposition=, create_options=, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result_fsp=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/modules/vfs_time_audit.c:634 - #36 0x00007fffa1559cbc in smb_vfs_call_create_file (handle=, req=, dirfsp=, smb_fname=, access_mask=, share_access=, create_disposition=, create_options=, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/vfs.c:1560 - #37 0x00007fffa1597aa8 in smbd_smb2_create_send (in_context_blobs=..., in_name=0x154413ca0, in_create_options=, in_create_disposition=, in_share_access=, in_file_attributes=, in_desired_access=, in_impersonation_level=, in_oplock_level=, smb2req=0x154413770, ev=0x154328120, mem_ctx=0x154413770) at ../../source3/smbd/smb2_create.c:1115 - #38 smbd_smb2_request_process_create (smb2req=0x154413770) at ../../source3/smbd/smb2_create.c:291 - #39 0x00007fffa158a628 in smbd_smb2_request_dispatch (req=0x154413770) at ../../source3/smbd/smb2_server.c:3485 - #40 0x00007fffa158c540 in smbd_smb2_io_handler (fde_flags=, xconn=0x154313f30) at ../../source3/smbd/smb2_server.c:5112 - #41 smbd_smb2_connection_handler (ev=, fde=, flags=, private_data=) at ../../source3/smbd/smb2_server.c:5150 - #42 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x15435add0, flags=, removed=0x0) at ../../lib/tevent/tevent_fd.c:158 - #43 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4b28, epoll_ev=0x1543b4e80) at ../../lib/tevent/tevent_epoll.c:730 - #44 epoll_event_loop_once (ev=, location=) at ../../lib/tevent/tevent_epoll.c:946 - #45 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:110 - #46 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent.c:823 - #47 0x00007fffa1197884 in tevent_common_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:950 - #48 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:141 - #49 0x00007fffa1197978 in _tevent_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:971 - #50 0x00007fffa15737fc in smbd_process (ev_ctx=0x154328120, msg_ctx=, sock_fd=, interactive=) at ../../source3/smbd/smb2_process.c:2158 - #51 0x000000011db5c554 in smbd_accept_connection (ev=0x154328120, fde=, flags=, private_data=) at ../../source3/smbd/server.c:1150 - #52 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543ac2d0, flags=, removed=0x0) at ../../lib/tevent/tevent_fd.c:158 - #53 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4f98, epoll_ev=0x154328350) at ../../lib/tevent/tevent_epoll.c:730 - #54 epoll_event_loop_once (ev=, location=) at ../../lib/tevent/tevent_epoll.c:946 - #55 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:110 - #56 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent.c:823 - #57 0x00007fffa1197884 in tevent_common_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:950 - #58 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:141 - #59 0x00007fffa1197978 in _tevent_loop_wait (ev=, location=) at ../../lib/tevent/tevent.c:971 - #60 0x000000011db58c54 in smbd_parent_loop (parent=, ev_ctx=0x154328120) at ../../source3/smbd/server.c:1499 - #61 main (argc=, argv=) at ../../source3/smbd/server.c:2258 - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Pair-Programmed-With: Stefan Metzmacher -Signed-off-by: Ralph Boehme -Signed-off-by: Stefan Metzmacher -(backported from commit 2eef298ff4c5baf15c7d29c65fb021dbed5b0a93) -[slow@samba.org: changed argument of share_mode_watch_send()] -[slow@samba.org: small context change in vfs_fruit] ---- - source3/locking/locking.c | 109 +++++-------------- - source3/locking/proto.h | 4 +- - source3/modules/vfs_fruit.c | 91 +++++++++++----- - source3/smbd/blocking.c | 202 +++++++++++++++++++----------------- - source3/smbd/proto.h | 19 ++-- - source3/smbd/smb2_lock.c | 77 +++++++++----- - source3/smbd/smb2_reply.c | 53 ++++++---- - 7 files changed, 293 insertions(+), 262 deletions(-) - -diff --git a/source3/locking/locking.c b/source3/locking/locking.c -index ea692711627..ffb89378cb5 100644 ---- a/source3/locking/locking.c -+++ b/source3/locking/locking.c -@@ -241,52 +241,7 @@ static void decrement_current_lock_count(files_struct *fsp, - Utility function called by locking requests. - ****************************************************************************/ - --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; -- enum brl_type lock_type; -- enum brl_flavour lock_flav; -- -- struct server_id blocker_pid; -- uint64_t blocker_smblctx; -- NTSTATUS status; --}; -- --static void do_lock_fn( -- struct share_mode_lock *lck, -- void *private_data) --{ -- struct do_lock_state *state = private_data; -- struct byte_range_lock *br_lck = NULL; -- -- 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; -- } -- -- state->status = brl_lock( -- br_lck, -- state->smblctx, -- messaging_server_id(state->fsp->conn->sconn->msg_ctx), -- state->offset, -- state->count, -- state->lock_type, -- state->lock_flav, -- &state->blocker_pid, -- &state->blocker_smblctx); -- -- TALLOC_FREE(br_lck); --} -- --NTSTATUS do_lock(files_struct *fsp, -+NTSTATUS do_lock(struct byte_range_lock *br_lck, - TALLOC_CTX *req_mem_ctx, - const struct GUID *req_guid, - uint64_t smblctx, -@@ -297,22 +252,13 @@ NTSTATUS do_lock(files_struct *fsp, - struct server_id *pblocker_pid, - uint64_t *psmblctx) - { -- struct do_lock_state state = { -- .fsp = fsp, -- .req_mem_ctx = req_mem_ctx, -- .req_guid = req_guid, -- .smblctx = smblctx, -- .count = count, -- .offset = offset, -- .lock_type = lock_type, -- .lock_flav = lock_flav, -- }; -+ files_struct *fsp = brl_fsp(br_lck); -+ struct server_id blocker_pid; -+ uint64_t blocker_smblctx; - NTSTATUS status; - -- /* silently return ok on print files as we don't do locking there */ -- if (fsp->print_file) { -- return NT_STATUS_OK; -- } -+ SMB_ASSERT(req_mem_ctx != NULL); -+ SMB_ASSERT(req_guid != NULL); - - if (!fsp->fsp_flags.can_lock) { - if (fsp->fsp_flags.is_directory) { -@@ -336,25 +282,27 @@ NTSTATUS do_lock(files_struct *fsp, - fsp_fnum_dbg(fsp), - fsp_str_dbg(fsp)); - -- status = share_mode_do_locked_vfs_allowed(fsp->file_id, -- do_lock_fn, -- &state); -- if (!NT_STATUS_IS_OK(status)) { -- DBG_DEBUG("share_mode_do_locked returned %s\n", -- nt_errstr(status)); -- return status; -- } -- if (!NT_STATUS_IS_OK(state.status)) { -- DBG_DEBUG("do_lock_fn returned %s\n", -- nt_errstr(state.status)); -+ brl_req_set(br_lck, req_mem_ctx, req_guid); -+ status = brl_lock(br_lck, -+ smblctx, -+ messaging_server_id(fsp->conn->sconn->msg_ctx), -+ offset, -+ count, -+ lock_type, -+ lock_flav, -+ &blocker_pid, -+ &blocker_smblctx); -+ brl_req_set(br_lck, NULL, NULL); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_DEBUG("brl_lock failed: %s\n", nt_errstr(status)); - if (psmblctx != NULL) { -- *psmblctx = state.blocker_smblctx; -+ *psmblctx = blocker_smblctx; - } - if (pblocker_pid != NULL) { -- *pblocker_pid = state.blocker_pid; -+ *pblocker_pid = blocker_pid; - } -- return state.status; -- } -+ return status; -+ } - - increment_current_lock_count(fsp, lock_flav); - -@@ -365,14 +313,14 @@ NTSTATUS do_lock(files_struct *fsp, - Utility function called by unlocking requests. - ****************************************************************************/ - --NTSTATUS do_unlock(files_struct *fsp, -+NTSTATUS do_unlock(struct byte_range_lock *br_lck, - uint64_t smblctx, - uint64_t count, - uint64_t offset, - enum brl_flavour lock_flav) - { -+ files_struct *fsp = brl_fsp(br_lck); - bool ok = False; -- struct byte_range_lock *br_lck = NULL; - - if (!fsp->fsp_flags.can_lock) { - return fsp->fsp_flags.is_directory ? -@@ -391,11 +339,6 @@ NTSTATUS do_unlock(files_struct *fsp, - fsp_fnum_dbg(fsp), - fsp_str_dbg(fsp)); - -- br_lck = brl_get_locks(talloc_tos(), fsp); -- if (!br_lck) { -- return NT_STATUS_NO_MEMORY; -- } -- - ok = brl_unlock(br_lck, - smblctx, - messaging_server_id(fsp->conn->sconn->msg_ctx), -@@ -403,8 +346,6 @@ NTSTATUS do_unlock(files_struct *fsp, - count, - lock_flav); - -- TALLOC_FREE(br_lck); -- - if (!ok) { - DEBUG(10,("do_unlock: returning ERRlock.\n" )); - return NT_STATUS_RANGE_NOT_LOCKED; -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index c74539c8161..e332abf34ec 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -120,7 +120,7 @@ NTSTATUS query_lock(files_struct *fsp, - uint64_t *poffset, - enum brl_type *plock_type, - enum brl_flavour lock_flav); --NTSTATUS do_lock(files_struct *fsp, -+NTSTATUS do_lock(struct byte_range_lock *br_lck, - TALLOC_CTX *req_mem_ctx, - const struct GUID *req_guid, - uint64_t smblctx, -@@ -130,7 +130,7 @@ NTSTATUS do_lock(files_struct *fsp, - enum brl_flavour lock_flav, - struct server_id *pblocker_pid, - uint64_t *psmblctx); --NTSTATUS do_unlock(files_struct *fsp, -+NTSTATUS do_unlock(struct byte_range_lock *br_lck, - uint64_t smblctx, - uint64_t count, - uint64_t offset, -diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c -index b63fff7f95d..e85c26c9dc0 100644 ---- a/source3/modules/vfs_fruit.c -+++ b/source3/modules/vfs_fruit.c -@@ -629,11 +629,21 @@ static bool test_netatalk_lock(files_struct *fsp, off_t in_offset) - return false; - } - --static NTSTATUS fruit_check_access(vfs_handle_struct *handle, -- files_struct *fsp, -- uint32_t access_mask, -- uint32_t share_mode) -+struct check_access_state { -+ NTSTATUS status; -+ files_struct *fsp; -+ uint32_t access_mask; -+ uint32_t share_mode; -+}; -+ -+static void fruit_check_access(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) - { -+ struct check_access_state *state = private_data; -+ files_struct *fsp = state->fsp; -+ uint32_t access_mask = state->access_mask; -+ uint32_t share_mode = state->share_mode; - NTSTATUS status = NT_STATUS_OK; - off_t off; - bool share_for_read = (share_mode & FILE_SHARE_READ); -@@ -647,6 +657,14 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - /* FIXME: hardcoded data fork, add resource fork */ - enum apple_fork fork_type = APPLE_FORK_DATA; - -+ /* -+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so -+ * br_lck has to be there! -+ */ -+ SMB_ASSERT(br_lck != NULL); -+ -+ state->status = NT_STATUS_OK; -+ - DBG_DEBUG("fruit_check_access: %s, am: %s/%s, sm: 0x%x\n", - fsp_str_dbg(fsp), - access_mask & FILE_READ_DATA ? "READ" :"-", -@@ -654,7 +672,7 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - share_mode); - - if (fsp_get_io_fd(fsp) == -1) { -- return NT_STATUS_OK; -+ return; - } - - /* Read NetATalk opens and deny modes on the file. */ -@@ -677,22 +695,26 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - /* If there are any conflicts - sharing violation. */ - if ((access_mask & FILE_READ_DATA) && - netatalk_already_open_with_deny_read) { -- return NT_STATUS_SHARING_VIOLATION; -+ state->status = NT_STATUS_SHARING_VIOLATION; -+ return; - } - - if (!share_for_read && - netatalk_already_open_for_reading) { -- return NT_STATUS_SHARING_VIOLATION; -+ state->status = NT_STATUS_SHARING_VIOLATION; -+ return; - } - - if ((access_mask & FILE_WRITE_DATA) && - netatalk_already_open_with_deny_write) { -- return NT_STATUS_SHARING_VIOLATION; -+ state->status = NT_STATUS_SHARING_VIOLATION; -+ return; - } - - if (!share_for_write && - netatalk_already_open_for_writing) { -- return NT_STATUS_SHARING_VIOLATION; -+ state->status = NT_STATUS_SHARING_VIOLATION; -+ return; - } - - if (!(access_mask & FILE_READ_DATA)) { -@@ -700,15 +722,16 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - * Nothing we can do here, we need read access - * to set locks. - */ -- return NT_STATUS_OK; -+ return; - } - - /* 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, -+ br_lck, - talloc_tos(), - &req_guid, - fsp->op->global->open_persistent_id, -@@ -718,17 +741,18 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - POSIX_LOCK, - NULL, - NULL); -- - if (!NT_STATUS_IS_OK(status)) { -- return status; -+ state->status = status; -+ return; - } - } - - if (!share_for_read) { - off = denymode_to_netatalk_brl(fork_type, DENY_READ); - req_guid.time_hi_and_version = __LINE__; -+ - status = do_lock( -- fsp, -+ br_lck, - talloc_tos(), - &req_guid, - fsp->op->global->open_persistent_id, -@@ -738,17 +762,18 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - POSIX_LOCK, - NULL, - NULL); -- - if (!NT_STATUS_IS_OK(status)) { -- return status; -+ state->status = status; -+ return; - } - } - - 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, -+ br_lck, - talloc_tos(), - &req_guid, - fsp->op->global->open_persistent_id, -@@ -758,17 +783,18 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - POSIX_LOCK, - NULL, - NULL); -- - if (!NT_STATUS_IS_OK(status)) { -- return status; -+ state->status = status; -+ return; - } - } - - if (!share_for_write) { - off = denymode_to_netatalk_brl(fork_type, DENY_WRITE); - req_guid.time_hi_and_version = __LINE__; -+ - status = do_lock( -- fsp, -+ br_lck, - talloc_tos(), - &req_guid, - fsp->op->global->open_persistent_id, -@@ -778,13 +804,11 @@ static NTSTATUS fruit_check_access(vfs_handle_struct *handle, - POSIX_LOCK, - NULL, - NULL); -- - if (!NT_STATUS_IS_OK(status)) { -- return status; -+ state->status = status; -+ return; - } - } -- -- return NT_STATUS_OK; - } - - static NTSTATUS check_aapl(vfs_handle_struct *handle, -@@ -4376,16 +4400,27 @@ static NTSTATUS fruit_create_file(vfs_handle_struct *handle, - } - - if ((config->locking == FRUIT_LOCKING_NETATALK) && -+ lp_locking(fsp->conn->params) && -+ fsp->fsp_flags.can_lock && - (fsp->op != NULL) && - !fsp->fsp_flags.is_pathref) - { -- status = fruit_check_access( -- handle, *result, -- access_mask, -- share_access); -+ struct check_access_state state = (struct check_access_state) { -+ .fsp = fsp, -+ .access_mask = access_mask, -+ .share_mode = share_access, -+ }; -+ -+ status = share_mode_do_locked_brl(fsp, -+ fruit_check_access, -+ &state); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } -+ if (!NT_STATUS_IS_OK(state.status)) { -+ status = state.status; -+ goto fail; -+ } - } - - return status; -diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c -index 8b41288bfbf..c9d9aff98b7 100644 ---- a/source3/smbd/blocking.c -+++ b/source3/smbd/blocking.c -@@ -29,31 +29,27 @@ - #undef DBGC_CLASS - #define DBGC_CLASS DBGC_LOCKING - --NTSTATUS smbd_do_locks_try( -- struct files_struct *fsp, -- uint16_t num_locks, -- struct smbd_lock_element *locks, -- uint16_t *blocker_idx, -- struct server_id *blocking_pid, -- uint64_t *blocking_smblctx) -+NTSTATUS smbd_do_locks_try(struct byte_range_lock *br_lck, -+ struct smbd_do_locks_state *state) - { -- NTSTATUS status = NT_STATUS_OK; -+ bool unlock_ok; - uint16_t i; -+ NTSTATUS status = NT_STATUS_OK; - -- for (i=0; inum_locks; i++) { -+ struct smbd_lock_element *e = &state->locks[i]; - - status = do_lock( -- fsp, -- locks, /* req_mem_ctx */ -+ br_lck, -+ state->locks, /* req_mem_ctx */ - &e->req_guid, - e->smblctx, - e->count, - e->offset, - e->brltype, - e->lock_flav, -- blocking_pid, -- blocking_smblctx); -+ &state->blocking_pid, -+ &state->blocking_smblctx); - if (!NT_STATUS_IS_OK(status)) { - break; - } -@@ -63,18 +59,35 @@ NTSTATUS smbd_do_locks_try( - return NT_STATUS_OK; - } - -- *blocker_idx = i; -+ state->blocker_idx = i; -+ unlock_ok = true; - - /* - * Undo the locks we successfully got - */ - for (i = i-1; i != UINT16_MAX; i--) { -- struct smbd_lock_element *e = &locks[i]; -- do_unlock(fsp, -- e->smblctx, -- e->count, -- e->offset, -- e->lock_flav); -+ struct smbd_lock_element *e = &state->locks[i]; -+ NTSTATUS ulstatus; -+ -+ ulstatus = do_unlock(br_lck, -+ e->smblctx, -+ e->count, -+ e->offset, -+ e->lock_flav); -+ if (!NT_STATUS_IS_OK(ulstatus)) { -+ DBG_DEBUG("Failed to undo lock flavour %s lock " -+ "type %s start=%"PRIu64" len=%"PRIu64" " -+ "requested for file [%s]\n", -+ lock_flav_name(e->lock_flav), -+ lock_type_name(e->brltype), -+ e->offset, -+ e->count, -+ fsp_str_dbg(brl_fsp(br_lck))); -+ unlock_ok = false; -+ } -+ } -+ if (unlock_ok) { -+ brl_set_modified(br_lck, false); - } - - return status; -@@ -118,13 +131,6 @@ 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, -- 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, -@@ -378,18 +384,35 @@ static NTSTATUS smbd_smb1_do_locks_check_blocked( - return NT_STATUS_OK; - } - --static NTSTATUS smbd_smb1_do_locks_check( -- struct files_struct *fsp, -- 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_try_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) - { -+ struct tevent_req *req = talloc_get_type_abort( -+ private_data, struct tevent_req); -+ struct smbd_smb1_do_locks_state *state = tevent_req_data( -+ req, struct smbd_smb1_do_locks_state); -+ struct smbd_do_locks_state brl_state; -+ struct files_struct *fsp = state->fsp; - struct tevent_req **blocked = fsp->blocked_smb1_lock_reqs; - size_t num_blocked = talloc_array_length(blocked); -- NTSTATUS status; -+ struct timeval endtime = { 0 }; -+ struct tevent_req *subreq = NULL; - size_t bi; -+ NTSTATUS status; -+ bool ok; -+ bool expired; -+ -+ /* -+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so -+ * br_lck has to be there! -+ */ -+ SMB_ASSERT(br_lck != NULL); -+ -+ brl_state = (struct smbd_do_locks_state) { -+ .num_locks = state->num_locks, -+ .locks = state->locks, -+ }; - - /* - * We check the pending/blocked requests -@@ -404,8 +427,8 @@ static NTSTATUS smbd_smb1_do_locks_check( - tevent_req_data(blocked[bi], - struct smbd_smb1_do_locks_state); - -- if (blocked_state->locks == locks) { -- SMB_ASSERT(blocked_state->num_locks == num_locks); -+ if (blocked_state->locks == state->locks) { -+ SMB_ASSERT(blocked_state->num_locks == state->num_locks); - - /* - * We found ourself... -@@ -416,61 +439,24 @@ static NTSTATUS smbd_smb1_do_locks_check( - status = smbd_smb1_do_locks_check_blocked( - blocked_state->num_locks, - blocked_state->locks, -- num_locks, -- locks, -- blocker_idx, -- blocking_smblctx); -+ state->num_locks, -+ state->locks, -+ &brl_state.blocker_idx, -+ &brl_state.blocking_smblctx); - if (!NT_STATUS_IS_OK(status)) { -- *blocking_pid = messaging_server_id( -- fsp->conn->sconn->msg_ctx); -- return status; -+ brl_state.blocking_pid = messaging_server_id( -+ fsp->conn->sconn->msg_ctx); -+ goto check_retry; - } - } - -- status = smbd_do_locks_try( -- fsp, -- 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 share_mode_lock *lck; -- struct timeval endtime = { 0 }; -- struct server_id blocking_pid = { 0 }; -- uint64_t blocking_smblctx = 0; -- struct tevent_req *subreq = NULL; -- NTSTATUS status; -- bool ok; -- bool expired; -- -- 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"); -- return; -- } -- -- status = smbd_smb1_do_locks_check( -- fsp, -- state->num_locks, -- state->locks, -- &state->blocker, -- &blocking_pid, -- &blocking_smblctx); -+ status = smbd_do_locks_try(br_lck, &brl_state); - if (NT_STATUS_IS_OK(status)) { - goto done; - } -+ -+ state->blocker = brl_state.blocker_idx; -+ - if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { - /* - * We got NT_STATUS_RETRY, -@@ -494,8 +480,8 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) - * locking.tdb may cause retries. - */ - -- if (blocking_smblctx != UINT64_MAX) { -- SMB_ASSERT(blocking_smblctx == 0); -+ if (brl_state.blocking_smblctx != UINT64_MAX) { -+ SMB_ASSERT(brl_state.blocking_smblctx == 0); - goto setup_retry; - } - -@@ -516,6 +502,8 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) - endtime = timeval_current_ofs_msec(state->retry_msecs); - goto setup_retry; - } -+ -+check_retry: - if (!ERROR_WAS_LOCK_DENIED(status)) { - goto done; - } -@@ -529,7 +517,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) - smbd_smb1_do_locks_setup_timeout(state, &state->locks[state->blocker]); - DBG_DEBUG("timeout=%"PRIu32", blocking_smblctx=%"PRIu64"\n", - state->timeout, -- blocking_smblctx); -+ brl_state.blocking_smblctx); - - /* - * The client specified timeout expired -@@ -554,7 +542,7 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) - - endtime = state->endtime; - -- if (blocking_smblctx == UINT64_MAX) { -+ if (brl_state.blocking_smblctx == UINT64_MAX) { - struct timeval tmp; - - smbd_smb1_do_locks_update_polling_msecs(state); -@@ -568,11 +556,11 @@ static void smbd_smb1_do_locks_try(struct tevent_req *req) - - setup_retry: - subreq = share_mode_watch_send( -- state, state->ev, lck, blocking_pid); -+ state, state->ev, lck, brl_state.blocking_pid); - if (tevent_req_nomem(subreq, req)) { -+ status = NT_STATUS_NO_MEMORY; - goto done; - } -- TALLOC_FREE(lck); - tevent_req_set_callback(subreq, smbd_smb1_do_locks_retry, req); - - if (timeval_is_zero(&endtime)) { -@@ -586,10 +574,38 @@ setup_retry: - } - return; - done: -- TALLOC_FREE(lck); - smbd_smb1_brl_finish_by_req(req, status); - } - -+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); -+ NTSTATUS status; -+ -+ if (!state->fsp->fsp_flags.can_lock) { -+ if (state->fsp->fsp_flags.is_directory) { -+ return smbd_smb1_brl_finish_by_req(req, -+ NT_STATUS_INVALID_DEVICE_REQUEST); -+ } -+ return smbd_smb1_brl_finish_by_req(req, -+ NT_STATUS_INVALID_HANDLE); -+ } -+ -+ if (!lp_locking(state->fsp->conn->params)) { -+ return smbd_smb1_brl_finish_by_req(req, NT_STATUS_OK); -+ } -+ -+ status = share_mode_do_locked_brl(state->fsp, -+ smbd_smb1_do_locks_try_fn, -+ req); -+ if (!NT_STATUS_IS_OK(status)) { -+ smbd_smb1_brl_finish_by_req(req, status); -+ return; -+ } -+ return; -+} -+ - static void smbd_smb1_do_locks_retry(struct tevent_req *subreq) - { - struct tevent_req *req = tevent_req_callback_data( -diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h -index 90387aeb6c3..5faf651b007 100644 ---- a/source3/smbd/proto.h -+++ b/source3/smbd/proto.h -@@ -86,13 +86,18 @@ ssize_t pwrite_fsync_recv(struct tevent_req *req, int *perr); - - /* The following definitions come from smbd/blocking.c */ - --NTSTATUS smbd_do_locks_try( -- struct files_struct *fsp, -- uint16_t num_locks, -- struct smbd_lock_element *locks, -- uint16_t *blocker_idx, -- struct server_id *blocking_pid, -- uint64_t *blocking_smblctx); -+struct smbd_do_locks_state { -+ uint16_t num_locks; -+ struct smbd_lock_element *locks; -+ NTSTATUS status; -+ uint16_t blocker_idx; -+ struct server_id blocking_pid; -+ uint64_t blocking_smblctx; -+}; -+ -+NTSTATUS smbd_do_locks_try(struct byte_range_lock *br_lck, -+ struct smbd_do_locks_state *state); -+ - struct tevent_req *smbd_smb1_do_locks_send( - TALLOC_CTX *mem_ctx, - struct tevent_context *ev, -diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c -index c9d810f71ba..14f912bf2da 100644 ---- a/source3/smbd/smb2_lock.c -+++ b/source3/smbd/smb2_lock.c -@@ -569,33 +569,32 @@ static void smbd_smb2_lock_update_polling_msecs( - state->polling_msecs += v_min; - } - --static void smbd_smb2_lock_try(struct tevent_req *req) -+static void smbd_do_locks_try_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) - { -+ struct tevent_req *req = talloc_get_type_abort( -+ private_data, struct tevent_req); - struct smbd_smb2_lock_state *state = tevent_req_data( - req, struct smbd_smb2_lock_state); -- struct share_mode_lock *lck = NULL; -- uint16_t blocker_idx; -- struct server_id blocking_pid = { 0 }; -- uint64_t blocking_smblctx; -- NTSTATUS status; -+ struct smbd_do_locks_state brl_state; - struct tevent_req *subreq = NULL; - struct timeval endtime = { 0 }; -+ NTSTATUS status; - -- lck = get_existing_share_mode_lock( -- talloc_tos(), state->fsp->file_id); -- if (tevent_req_nomem(lck, req)) { -- return; -- } -+ /* -+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so -+ * br_lck has to be there! -+ */ -+ SMB_ASSERT(br_lck != NULL); - -- status = smbd_do_locks_try( -- state->fsp, -- state->lock_count, -- state->locks, -- &blocker_idx, -- &blocking_pid, -- &blocking_smblctx); -+ brl_state = (struct smbd_do_locks_state) { -+ .num_locks = state->lock_count, -+ .locks = state->locks, -+ }; -+ -+ status = smbd_do_locks_try(br_lck, &brl_state); - if (NT_STATUS_IS_OK(status)) { -- TALLOC_FREE(lck); - tevent_req_done(req); - return; - } -@@ -622,8 +621,8 @@ static void smbd_smb2_lock_try(struct tevent_req *req) - * locking.tdb may cause retries. - */ - -- if (blocking_smblctx != UINT64_MAX) { -- SMB_ASSERT(blocking_smblctx == 0); -+ if (brl_state.blocking_smblctx != UINT64_MAX) { -+ SMB_ASSERT(brl_state.blocking_smblctx == 0); - goto setup_retry; - } - -@@ -658,7 +657,6 @@ static void smbd_smb2_lock_try(struct tevent_req *req) - 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; - } -@@ -670,12 +668,11 @@ static void smbd_smb2_lock_try(struct tevent_req *req) - state->retry_msecs = 0; - - if (!state->blocking) { -- TALLOC_FREE(lck); - tevent_req_nterror(req, status); - return; - } - -- if (blocking_smblctx == UINT64_MAX) { -+ if (brl_state.blocking_smblctx == UINT64_MAX) { - smbd_smb2_lock_update_polling_msecs(state); - - DBG_DEBUG("Blocked on a posix lock. Retry in %"PRIu32" msecs\n", -@@ -688,8 +685,7 @@ setup_retry: - DBG_DEBUG("Watching share mode lock\n"); - - subreq = share_mode_watch_send( -- state, state->ev, lck, blocking_pid); -- TALLOC_FREE(lck); -+ state, state->ev, lck, brl_state.blocking_pid); - if (tevent_req_nomem(subreq, req)) { - return; - } -@@ -708,6 +704,35 @@ setup_retry: - } - } - -+static void smbd_smb2_lock_try(struct tevent_req *req) -+{ -+ struct smbd_smb2_lock_state *state = tevent_req_data( -+ req, struct smbd_smb2_lock_state); -+ NTSTATUS status; -+ -+ if (!state->fsp->fsp_flags.can_lock) { -+ if (state->fsp->fsp_flags.is_directory) { -+ tevent_req_nterror(req, -+ NT_STATUS_INVALID_DEVICE_REQUEST); -+ return; -+ } -+ tevent_req_nterror(req, NT_STATUS_INVALID_HANDLE); -+ return; -+ } -+ -+ if (!lp_locking(state->fsp->conn->params)) { -+ return tevent_req_done(req); -+ } -+ -+ status = share_mode_do_locked_brl(state->fsp, -+ smbd_do_locks_try_fn, -+ req); -+ if (!NT_STATUS_IS_OK(status)) { -+ tevent_req_nterror(req, status); -+ return; -+ } -+} -+ - static void smbd_smb2_lock_retry(struct tevent_req *subreq) - { - struct tevent_req *req = tevent_req_callback_data( -diff --git a/source3/smbd/smb2_reply.c b/source3/smbd/smb2_reply.c -index 2b65fb30d76..3de36a7d673 100644 ---- a/source3/smbd/smb2_reply.c -+++ b/source3/smbd/smb2_reply.c -@@ -2122,23 +2122,22 @@ uint64_t get_lock_offset(const uint8_t *data, int data_offset, - return offset; - } - --struct smbd_do_unlocking_state { -- struct files_struct *fsp; -- uint16_t num_ulocks; -- struct smbd_lock_element *ulocks; -- NTSTATUS status; --}; -- --static void smbd_do_unlocking_fn( -- struct share_mode_lock *lck, -- void *private_data) -+static void smbd_do_unlocking_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) - { -- struct smbd_do_unlocking_state *state = private_data; -- struct files_struct *fsp = state->fsp; -+ struct smbd_do_locks_state *state = private_data; -+ struct files_struct *fsp = brl_fsp(br_lck); - uint16_t i; - -- for (i = 0; i < state->num_ulocks; i++) { -- struct smbd_lock_element *e = &state->ulocks[i]; -+ /* -+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so -+ * br_lck has to be there! -+ */ -+ SMB_ASSERT(br_lck != NULL); -+ -+ for (i = 0; i < state->num_locks; i++) { -+ struct smbd_lock_element *e = &state->locks[i]; - - DBG_DEBUG("unlock start=%"PRIu64", len=%"PRIu64" for " - "pid %"PRIu64", file %s\n", -@@ -2154,7 +2153,7 @@ static void smbd_do_unlocking_fn( - } - - state->status = do_unlock( -- fsp, e->smblctx, e->count, e->offset, e->lock_flav); -+ br_lck, e->smblctx, e->count, e->offset, e->lock_flav); - - DBG_DEBUG("do_unlock returned %s\n", - nt_errstr(state->status)); -@@ -2172,20 +2171,30 @@ NTSTATUS smbd_do_unlocking(struct smb_request *req, - uint16_t num_ulocks, - struct smbd_lock_element *ulocks) - { -- struct smbd_do_unlocking_state state = { -- .fsp = fsp, -- .num_ulocks = num_ulocks, -- .ulocks = ulocks, -+ struct smbd_do_locks_state state = { -+ .num_locks = num_ulocks, -+ .locks = ulocks, - }; - NTSTATUS status; - - DBG_NOTICE("%s num_ulocks=%"PRIu16"\n", fsp_fnum_dbg(fsp), num_ulocks); - -- status = share_mode_do_locked_vfs_allowed( -- fsp->file_id, smbd_do_unlocking_fn, &state); -+ if (!fsp->fsp_flags.can_lock) { -+ if (fsp->fsp_flags.is_directory) { -+ return NT_STATUS_INVALID_DEVICE_REQUEST; -+ } -+ return NT_STATUS_INVALID_HANDLE; -+ } -+ -+ if (!lp_locking(fsp->conn->params)) { -+ return NT_STATUS_OK; -+ } - -+ status = share_mode_do_locked_brl(fsp, -+ smbd_do_unlocking_fn, -+ &state); - if (!NT_STATUS_IS_OK(status)) { -- DBG_DEBUG("share_mode_do_locked_vfs_allowed failed: %s\n", -+ DBG_DEBUG("share_mode_do_locked_brl failed: %s\n", - nt_errstr(status)); - return status; - } --- -2.51.0 - - -From 45211424de82b03e187369286034b7c49136ba5f Mon Sep 17 00:00:00 2001 -From: Stefan Metzmacher -Date: Wed, 8 Jan 2025 12:51:37 +0100 -Subject: [PATCH 17/43] s3/brlock: remove brl_get_locks_for_locking() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Pair-Programmed-With: Ralph Boehme -Signed-off-by: Ralph Boehme -Signed-off-by: Stefan Metzmacher -(cherry picked from commit 0c4c430c50e15d591a0d871a5f3e59e8be0d0a83) ---- - source3/locking/brlock.c | 19 ------------------- - source3/locking/proto.h | 4 ---- - 2 files changed, 23 deletions(-) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index 0e58339b108..b9decbc9e2a 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -1733,25 +1733,6 @@ 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; -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index e332abf34ec..44b43c1b1e2 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -83,10 +83,6 @@ 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 share_mode_lock; - typedef void (*share_mode_do_locked_brl_fn_t)( - struct share_mode_lock *lck, --- -2.51.0 - - -From ef4e89916360c8d7f2372c8508c8a79dfd995c47 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Mon, 27 Jan 2025 15:22:26 +0100 -Subject: [PATCH 18/43] smbd: call locking_close_file() while still holding a - glock on the locking.tdb record - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 4d680b6c17ee7674b9686aec2b69038f89e1989a) ---- - source3/smbd/close.c | 26 +++++++++++++++++++------- - 1 file changed, 19 insertions(+), 7 deletions(-) - -diff --git a/source3/smbd/close.c b/source3/smbd/close.c -index 1b027a319a4..964c3530e8d 100644 ---- a/source3/smbd/close.c -+++ b/source3/smbd/close.c -@@ -303,6 +303,17 @@ static void close_share_mode_lock_prepare(struct share_mode_lock *lck, - */ - *keep_locked = false; - -+ if (fsp->current_lock_count > 0) { -+ /* -+ * Remove the byte-range locks under the glock -+ */ -+ *keep_locked = true; -+ } -+ -+ if (fh_get_refcount(fsp->fh) > 1) { -+ return; -+ } -+ - if (fsp->oplock_type != NO_OPLOCK) { - ok = remove_share_oplock(lck, fsp); - if (!ok) { -@@ -453,6 +464,12 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp, - return status; - } - -+ locking_close_file(fsp, close_type); -+ -+ if (fh_get_refcount(fsp->fh) > 1) { -+ goto done; -+ } -+ - /* Remove the oplock before potentially deleting the file. */ - if (fsp->oplock_type != NO_OPLOCK) { - release_file_oplock(fsp); -@@ -890,13 +907,8 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, - the same handle we only have one share mode. Ensure we only remove - the share mode on the last close. */ - -- if (fh_get_refcount(fsp->fh) == 1) { -- /* Should we return on error here... ? */ -- tmp = close_remove_share_mode(fsp, close_type); -- status = ntstatus_keeperror(status, tmp); -- } -- -- locking_close_file(fsp, close_type); -+ tmp = close_remove_share_mode(fsp, close_type); -+ status = ntstatus_keeperror(status, tmp); - - /* - * Ensure pending modtime is set before closing underlying fd. --- -2.51.0 - - -From 96d3bacbd967b355c91bc1d9e583edb1cdd3bd19 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 30 Jan 2025 17:35:26 +0100 -Subject: [PATCH 19/43] s3/locking: prepare brl_locktest() for upgradable - read-only locks - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 8f9387ceb5c94c7db92ab342e33c64b858c301b1) ---- - source3/locking/brlock.c | 5 +++-- - source3/locking/locking.c | 4 ++-- - source3/locking/proto.h | 3 ++- - 3 files changed, 7 insertions(+), 5 deletions(-) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index b9decbc9e2a..92621c41577 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -1192,7 +1192,8 @@ bool brl_unlock(struct byte_range_lock *br_lck, - ****************************************************************************/ - - bool brl_locktest(struct byte_range_lock *br_lck, -- const struct lock_struct *rw_probe) -+ const struct lock_struct *rw_probe, -+ bool upgradable) - { - bool ret = True; - unsigned int i; -@@ -1205,7 +1206,7 @@ bool brl_locktest(struct byte_range_lock *br_lck, - * Our own locks don't conflict. - */ - if (brl_conflict_other(&locks[i], rw_probe)) { -- if (br_lck->record == NULL) { -+ if (!upgradable) { - /* readonly */ - return false; - } -diff --git a/source3/locking/locking.c b/source3/locking/locking.c -index ffb89378cb5..993d3a96591 100644 ---- a/source3/locking/locking.c -+++ b/source3/locking/locking.c -@@ -145,7 +145,7 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock) - if (!br_lck) { - return true; - } -- ret = brl_locktest(br_lck, plock); -+ ret = brl_locktest(br_lck, plock, false); - - if (!ret) { - /* -@@ -156,7 +156,7 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock) - if (br_lck == NULL) { - return true; - } -- ret = brl_locktest(br_lck, plock); -+ ret = brl_locktest(br_lck, plock, true); - TALLOC_FREE(br_lck); - } - -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index 44b43c1b1e2..44808171f1a 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -66,7 +66,8 @@ bool brl_unlock(struct byte_range_lock *br_lck, - bool brl_unlock_windows_default(struct byte_range_lock *br_lck, - const struct lock_struct *plock); - bool brl_locktest(struct byte_range_lock *br_lck, -- const struct lock_struct *rw_probe); -+ const struct lock_struct *rw_probe, -+ bool upgradable); - NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, - uint64_t *psmblctx, - struct server_id pid, --- -2.51.0 - - -From b88988bcc9ce1fa0b8152e0eb89cb496f675fbc1 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Wed, 2 Apr 2025 12:43:15 +0200 -Subject: [PATCH 20/43] smbd: check can_lock in strict_lock_check_default() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Pair-Programmed-With: Stefan Metzmacher -Signed-off-by: Ralph Boehme -Signed-off-by: Stefan Metzmacher -(cherry picked from commit 678f28c1af7c160ffdcb0e4baa0a7d4b9906f2e5) ---- - source3/locking/locking.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/source3/locking/locking.c b/source3/locking/locking.c -index 993d3a96591..ce2ccaccd11 100644 ---- a/source3/locking/locking.c -+++ b/source3/locking/locking.c -@@ -117,7 +117,10 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock) - return True; - } - -- if (!lp_locking(fsp->conn->params) || !strict_locking) { -+ if (!lp_locking(fsp->conn->params) || -+ !strict_locking || -+ !fsp->fsp_flags.can_lock) -+ { - return True; - } - --- -2.51.0 - - -From e5d8f12b8ecfcd52ec8dc32147b1f2c6d8115c37 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Thu, 30 Jan 2025 07:40:32 +0100 -Subject: [PATCH 21/43] smbd: use share_mode_do_locked_brl() in - strict_lock_check_default() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit 56bb20c87a733ab8f7efedd881ea0ecaf51b2ba8) ---- - source3/locking/locking.c | 43 +++++++++++++++++++++++++++++++++------ - 1 file changed, 37 insertions(+), 6 deletions(-) - -diff --git a/source3/locking/locking.c b/source3/locking/locking.c -index ce2ccaccd11..ddaa5405f02 100644 ---- a/source3/locking/locking.c -+++ b/source3/locking/locking.c -@@ -107,10 +107,32 @@ void init_strict_lock_struct(files_struct *fsp, - }; - } - -+struct strict_lock_check_state { -+ bool ret; -+ files_struct *fsp; -+ struct lock_struct *plock; -+}; -+ -+static void strict_lock_check_default_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) -+{ -+ struct strict_lock_check_state *state = private_data; -+ -+ /* -+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so -+ * br_lck has to be there! -+ */ -+ SMB_ASSERT(br_lck != NULL); -+ -+ state->ret = brl_locktest(br_lck, state->plock, true); -+} -+ - bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock) - { - struct byte_range_lock *br_lck; - int strict_locking = lp_strict_locking(fsp->conn->params); -+ NTSTATUS status; - bool ret = False; - - if (plock->size == 0) { -@@ -149,18 +171,27 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock) - return true; - } - ret = brl_locktest(br_lck, plock, false); -- - if (!ret) { - /* - * We got a lock conflict. Retry with rw locks to enable - * autocleanup. This is the slow path anyway. - */ -- br_lck = brl_get_locks(talloc_tos(), fsp); -- if (br_lck == NULL) { -- return true; -+ -+ struct strict_lock_check_state state = -+ (struct strict_lock_check_state) { -+ .fsp = fsp, -+ .plock = plock, -+ }; -+ -+ status = share_mode_do_locked_brl(fsp, -+ strict_lock_check_default_fn, -+ &state); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("share_mode_do_locked_brl [%s] failed: %s\n", -+ fsp_str_dbg(fsp), nt_errstr(status)); -+ state.ret = false; - } -- ret = brl_locktest(br_lck, plock, true); -- TALLOC_FREE(br_lck); -+ ret = state.ret; - } - - DBG_DEBUG("flavour = %s brl start=%" PRIu64 " " --- -2.51.0 - - -From c26eded8448722126d73f3113da6b27378185475 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Tue, 28 Jan 2025 11:19:05 +0100 -Subject: [PATCH 22/43] smbd: use share_mode_do_locked_brl() in - vfs_default_durable_disconnect() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(backported from commit 393379fc9c726eb781fd1bfb3a70ea2802739aff) -[slow@samba.org: conflict due to removed delayed write time handling] ---- - source3/locking/brlock.c | 14 +---- - source3/locking/proto.h | 9 ++- - source3/smbd/durable.c | 117 ++++++++++++++++++++++++--------------- - 3 files changed, 82 insertions(+), 58 deletions(-) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index 92621c41577..4dcae87691b 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -1368,14 +1368,14 @@ void brl_close_fnum(struct byte_range_lock *br_lck) - } - } - --bool brl_mark_disconnected(struct files_struct *fsp) -+bool brl_mark_disconnected(struct files_struct *fsp, -+ struct byte_range_lock *br_lck) - { - uint32_t tid = fsp->conn->cnum; - uint64_t smblctx; - uint64_t fnum = fsp->fnum; - unsigned int i; - struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx); -- struct byte_range_lock *br_lck = NULL; - - if (fsp->op == NULL) { - return false; -@@ -1391,11 +1391,6 @@ bool brl_mark_disconnected(struct files_struct *fsp) - return true; - } - -- br_lck = brl_get_locks(talloc_tos(), fsp); -- if (br_lck == NULL) { -- return false; -- } -- - for (i=0; i < br_lck->num_locks; i++) { - struct lock_struct *lock = &br_lck->lock_data[i]; - -@@ -1405,22 +1400,18 @@ bool brl_mark_disconnected(struct files_struct *fsp) - */ - - if (lock->context.smblctx != smblctx) { -- TALLOC_FREE(br_lck); - return false; - } - - if (lock->context.tid != tid) { -- TALLOC_FREE(br_lck); - return false; - } - - if (!server_id_equal(&lock->context.pid, &self)) { -- TALLOC_FREE(br_lck); - return false; - } - - if (lock->fnum != fnum) { -- TALLOC_FREE(br_lck); - return false; - } - -@@ -1430,7 +1421,6 @@ bool brl_mark_disconnected(struct files_struct *fsp) - } - - br_lck->modified = true; -- TALLOC_FREE(br_lck); - return true; - } - -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index 44808171f1a..d3b4e02bc26 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -75,7 +75,14 @@ NTSTATUS brl_lockquery(struct byte_range_lock *br_lck, - br_off *psize, - enum brl_type *plock_type, - enum brl_flavour lock_flav); --bool brl_mark_disconnected(struct files_struct *fsp); -+ -+struct brl_connectstate { -+ bool ok; -+ struct files_struct *fsp; -+}; -+ -+bool brl_mark_disconnected(struct files_struct *fsp, -+ struct byte_range_lock *br_lck); - bool brl_reconnect_disconnected(struct files_struct *fsp); - void brl_close_fnum(struct byte_range_lock *br_lck); - int brl_forall(void (*fn)(struct file_id id, struct server_id pid, -diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c -index bd0c9f58e24..d315cb21ccc 100644 ---- a/source3/smbd/durable.c -+++ b/source3/smbd/durable.c -@@ -133,6 +133,63 @@ NTSTATUS vfs_default_durable_cookie(struct files_struct *fsp, - return NT_STATUS_OK; - } - -+struct durable_disconnect_state { -+ NTSTATUS status; -+ struct files_struct *fsp; -+}; -+ -+static void default_durable_disconnect_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) -+{ -+ struct durable_disconnect_state *state = private_data; -+ struct files_struct *fsp = state->fsp; -+ struct smb_file_time ft; -+ bool ok; -+ -+ /* Ensure any pending write time updates are done. */ -+ if (fsp->update_write_time_event) { -+ fsp_flush_write_time_update(fsp); -+ } -+ -+ -+ init_smb_file_time(&ft); -+ -+ if (fsp->fsp_flags.write_time_forced) { -+ NTTIME mtime = share_mode_changed_write_time(lck); -+ ft.mtime = nt_time_to_full_timespec(mtime); -+ } else if (fsp->fsp_flags.update_write_time_on_close) { -+ if (is_omit_timespec(&fsp->close_write_time)) { -+ ft.mtime = timespec_current(); -+ } else { -+ ft.mtime = fsp->close_write_time; -+ } -+ } -+ -+ if (!is_omit_timespec(&ft.mtime)) { -+ round_timespec(fsp->conn->ts_res, &ft.mtime); -+ file_ntimes(fsp->conn, fsp, &ft); -+ } -+ -+ ok = mark_share_mode_disconnected(lck, fsp); -+ if (!ok) { -+ state->status = NT_STATUS_UNSUCCESSFUL; -+ return; -+ } -+ -+ if (br_lck == NULL) { -+ state->status = NT_STATUS_OK; -+ return; -+ } -+ -+ ok = brl_mark_disconnected(fsp, br_lck); -+ if (!ok) { -+ state->status = NT_STATUS_UNSUCCESSFUL; -+ return; -+ } -+ state->status = NT_STATUS_OK; -+} -+ - NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp, - const DATA_BLOB old_cookie, - TALLOC_CTX *mem_ctx, -@@ -143,8 +200,7 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp, - enum ndr_err_code ndr_err; - struct vfs_default_durable_cookie cookie; - DATA_BLOB new_cookie_blob = data_blob_null; -- struct share_mode_lock *lck; -- bool ok; -+ struct durable_disconnect_state state; - - *new_cookie = data_blob_null; - -@@ -198,52 +254,23 @@ NTSTATUS vfs_default_durable_disconnect(struct files_struct *fsp, - return NT_STATUS_NOT_SUPPORTED; - } - -- /* Ensure any pending write time updates are done. */ -- if (fsp->update_write_time_event) { -- fsp_flush_write_time_update(fsp); -- } -+ state = (struct durable_disconnect_state) { -+ .fsp = fsp, -+ }; - -- /* -- * The above checks are done in mark_share_mode_disconnected() too -- * but we want to avoid getting the lock if possible -- */ -- lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id); -- if (lck != NULL) { -- struct smb_file_time ft; -- -- init_smb_file_time(&ft); -- -- if (fsp->fsp_flags.write_time_forced) { -- NTTIME mtime = share_mode_changed_write_time(lck); -- ft.mtime = nt_time_to_full_timespec(mtime); -- } else if (fsp->fsp_flags.update_write_time_on_close) { -- if (is_omit_timespec(&fsp->close_write_time)) { -- ft.mtime = timespec_current(); -- } else { -- ft.mtime = fsp->close_write_time; -- } -- } -- -- if (!is_omit_timespec(&ft.mtime)) { -- round_timespec(conn->ts_res, &ft.mtime); -- file_ntimes(conn, fsp, &ft); -- } -- -- ok = mark_share_mode_disconnected(lck, fsp); -- if (!ok) { -- TALLOC_FREE(lck); -- } -- } -- if (lck != NULL) { -- ok = brl_mark_disconnected(fsp); -- if (!ok) { -- TALLOC_FREE(lck); -- } -+ status = share_mode_do_locked_brl(fsp, -+ default_durable_disconnect_fn, -+ &state); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("share_mode_do_locked_brl [%s] failed: %s\n", -+ fsp_str_dbg(fsp), nt_errstr(status)); -+ return status; - } -- if (lck == NULL) { -- return NT_STATUS_NOT_SUPPORTED; -+ if (!NT_STATUS_IS_OK(state.status)) { -+ DBG_ERR("default_durable_disconnect_fn [%s] failed: %s\n", -+ fsp_str_dbg(fsp), nt_errstr(state.status)); -+ return state.status; - } -- TALLOC_FREE(lck); - - status = vfs_stat_fsp(fsp); - if (!NT_STATUS_IS_OK(status)) { --- -2.51.0 - - -From 33afc50416b09f2c025975fd7a98686f046005ae Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Wed, 2 Apr 2025 14:52:03 +0200 -Subject: [PATCH 23/43] smbd: use share_mode_do_locked_brl() in - vfs_default_durable_reconnect() - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(backported from commit dc03a06ffcc79d0818ae4a36fe3f2df705144138) -[slow@samba.org: conflict due to removed delayed write time handling] -[slow@samba.org: conflict due to filename_convert_dirfsp_rel()] ---- - source3/locking/brlock.c | 15 +- - source3/locking/proto.h | 3 +- - source3/smbd/durable.c | 439 ++++++++++++++++++++------------------- - 3 files changed, 234 insertions(+), 223 deletions(-) - -diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c -index 4dcae87691b..edc5c34ebc3 100644 ---- a/source3/locking/brlock.c -+++ b/source3/locking/brlock.c -@@ -1424,14 +1424,14 @@ bool brl_mark_disconnected(struct files_struct *fsp, - return true; - } - --bool brl_reconnect_disconnected(struct files_struct *fsp) -+bool brl_reconnect_disconnected(struct files_struct *fsp, -+ struct byte_range_lock *br_lck) - { - uint32_t tid = fsp->conn->cnum; - uint64_t smblctx; - uint64_t fnum = fsp->fnum; - unsigned int i; - struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx); -- struct byte_range_lock *br_lck = NULL; - - if (fsp->op == NULL) { - return false; -@@ -1449,13 +1449,7 @@ bool brl_reconnect_disconnected(struct files_struct *fsp) - * them instead. - */ - -- br_lck = brl_get_locks(talloc_tos(), fsp); -- if (br_lck == NULL) { -- return false; -- } -- - if (br_lck->num_locks == 0) { -- TALLOC_FREE(br_lck); - return true; - } - -@@ -1468,22 +1462,18 @@ bool brl_reconnect_disconnected(struct files_struct *fsp) - */ - - if (lock->context.smblctx != smblctx) { -- TALLOC_FREE(br_lck); - return false; - } - - if (lock->context.tid != TID_FIELD_INVALID) { -- TALLOC_FREE(br_lck); - return false; - } - - if (!server_id_is_disconnected(&lock->context.pid)) { -- TALLOC_FREE(br_lck); - return false; - } - - if (lock->fnum != FNUM_FIELD_INVALID) { -- TALLOC_FREE(br_lck); - return false; - } - -@@ -1494,7 +1484,6 @@ bool brl_reconnect_disconnected(struct files_struct *fsp) - - fsp->current_lock_count = br_lck->num_locks; - br_lck->modified = true; -- TALLOC_FREE(br_lck); - return true; - } - -diff --git a/source3/locking/proto.h b/source3/locking/proto.h -index d3b4e02bc26..37d382833fc 100644 ---- a/source3/locking/proto.h -+++ b/source3/locking/proto.h -@@ -83,7 +83,8 @@ struct brl_connectstate { - - bool brl_mark_disconnected(struct files_struct *fsp, - struct byte_range_lock *br_lck); --bool brl_reconnect_disconnected(struct files_struct *fsp); -+bool brl_reconnect_disconnected(struct files_struct *fsp, -+ struct byte_range_lock *br_lck); - void brl_close_fnum(struct byte_range_lock *br_lck); - int brl_forall(void (*fn)(struct file_id id, struct server_id pid, - enum brl_type lock_type, -diff --git a/source3/smbd/durable.c b/source3/smbd/durable.c -index d315cb21ccc..82777d3b81b 100644 ---- a/source3/smbd/durable.c -+++ b/source3/smbd/durable.c -@@ -563,121 +563,42 @@ static bool durable_reconnect_fn( - return false; /* Look at potential other entries */ - } - --NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, -- struct smb_request *smb1req, -- struct smbXsrv_open *op, -- const DATA_BLOB old_cookie, -- TALLOC_CTX *mem_ctx, -- files_struct **result, -- DATA_BLOB *new_cookie) -+struct vfs_default_durable_reconnect_state { -+ NTSTATUS status; -+ TALLOC_CTX *mem_ctx; -+ struct smb_request *smb1req; -+ struct smbXsrv_open *op; -+ struct vfs_default_durable_cookie cookie; -+ struct files_struct *fsp; -+ DATA_BLOB new_cookie_blob; -+}; -+ -+static void vfs_default_durable_reconnect_fn(struct share_mode_lock *lck, -+ struct byte_range_lock *br_lck, -+ void *private_data) - { -+ struct vfs_default_durable_reconnect_state *state = private_data; - const struct loadparm_substitution *lp_sub = - loadparm_s3_global_substitution(); -- struct share_mode_lock *lck; -+ struct files_struct *fsp = state->fsp; - struct share_mode_entry e = { .pid = { .pid = 0, }}; -- struct durable_reconnect_state rstate = { .op = op, .e = &e, }; -- struct files_struct *fsp = NULL; -- NTSTATUS status; -- bool ok; -- int ret; -+ struct durable_reconnect_state rstate = { .op = state->op, .e = &e, }; - struct vfs_open_how how = { .flags = 0, }; - struct file_id file_id; -- struct smb_filename *smb_fname = NULL; -- enum ndr_err_code ndr_err; -- struct vfs_default_durable_cookie cookie; -- DATA_BLOB new_cookie_blob = data_blob_null; - bool have_share_mode_entry = false; -- -- *result = NULL; -- *new_cookie = data_blob_null; -- -- if (!lp_durable_handles(SNUM(conn))) { -- return NT_STATUS_NOT_SUPPORTED; -- } -- -- /* -- * the checks for kernel oplocks -- * and similar things are done -- * in the vfs_default_durable_cookie() -- * call below. -- */ -- -- ndr_err = ndr_pull_struct_blob_all( -- &old_cookie, -- talloc_tos(), -- &cookie, -- (ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie); -- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -- status = ndr_map_error2ntstatus(ndr_err); -- return status; -- } -- -- if (strcmp(cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) { -- return NT_STATUS_INVALID_PARAMETER; -- } -- -- if (cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) { -- return NT_STATUS_INVALID_PARAMETER; -- } -- -- if (!cookie.allow_reconnect) { -- return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- } -- -- if (strcmp(cookie.servicepath, conn->connectpath) != 0) { -- return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- } -- -- /* Create an smb_filename with stream_name == NULL. */ -- smb_fname = synthetic_smb_fname(talloc_tos(), -- cookie.base_name, -- NULL, -- NULL, -- 0, -- 0); -- if (smb_fname == NULL) { -- return NT_STATUS_NO_MEMORY; -- } -- -- ret = SMB_VFS_LSTAT(conn, smb_fname); -- if (ret == -1) { -- status = map_nt_error_from_unix_common(errno); -- DEBUG(1, ("Unable to lstat stream: %s => %s\n", -- smb_fname_str_dbg(smb_fname), -- nt_errstr(status))); -- return status; -- } -- -- if (!S_ISREG(smb_fname->st.st_ex_mode)) { -- return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- } -- -- file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st); -- if (!file_id_equal(&cookie.id, &file_id)) { -- return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- } -- -- /* -- * 1. check entry in locking.tdb -- */ -- -- lck = get_existing_share_mode_lock(mem_ctx, file_id); -- if (lck == NULL) { -- DEBUG(5, ("vfs_default_durable_reconnect: share-mode lock " -- "not obtained from db\n")); -- return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- } -+ int ret; -+ bool ok; - - ok = share_mode_forall_entries(lck, durable_reconnect_fn, &rstate); - if (!ok) { - DBG_WARNING("share_mode_forall_entries failed\n"); -- status = NT_STATUS_INTERNAL_DB_ERROR; -+ state->status = NT_STATUS_INTERNAL_DB_ERROR; - goto fail; - } - - if (e.pid.pid == 0) { - DBG_WARNING("Did not find a unique valid share mode entry\n"); -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - -@@ -685,69 +606,36 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, - DEBUG(5, ("vfs_default_durable_reconnect: denying durable " - "reconnect for handle that was not marked " - "disconnected (e.g. smbd or cluster node died)\n")); -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - -- if (e.share_file_id != op->global->open_persistent_id) { -+ if (e.share_file_id != state->op->global->open_persistent_id) { - DBG_INFO("denying durable " - "share_file_id changed %"PRIu64" != %"PRIu64" " - "(e.g. another client had opened the file)\n", - e.share_file_id, -- op->global->open_persistent_id); -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->op->global->open_persistent_id); -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - - if ((e.access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) && -- !CAN_WRITE(conn)) -+ !CAN_WRITE(fsp->conn)) - { - DEBUG(5, ("vfs_default_durable_reconnect: denying durable " - "share[%s] is not writeable anymore\n", -- lp_servicename(talloc_tos(), lp_sub, SNUM(conn)))); -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -- goto fail; -- } -- -- /* -- * 2. proceed with opening file -- */ -- -- status = fsp_new(conn, conn, &fsp); -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(0, ("vfs_default_durable_reconnect: failed to create " -- "new fsp: %s\n", nt_errstr(status))); -+ lp_servicename(talloc_tos(), lp_sub, SNUM(fsp->conn)))); -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - - fh_set_private_options(fsp->fh, e.private_options); -- fsp->file_id = file_id; -- fsp->file_pid = smb1req->smbpid; -- fsp->vuid = smb1req->vuid; - fsp->open_time = e.time; - fsp->access_mask = e.access_mask; - fsp->fsp_flags.can_read = ((fsp->access_mask & FILE_READ_DATA) != 0); - fsp->fsp_flags.can_write = ((fsp->access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) != 0); -- fsp->fnum = op->local_id; -- fsp_set_gen_id(fsp); - -- /* -- * TODO: -- * Do we need to store the modified flag in the DB? -- */ -- fsp->fsp_flags.modified = false; -- /* -- * no durables for directories -- */ -- fsp->fsp_flags.is_directory = false; -- /* -- * For normal files, can_lock == !is_directory -- */ -- fsp->fsp_flags.can_lock = true; -- /* -- * We do not support aio write behind for smb2 -- */ -- fsp->fsp_flags.aio_write_behind = false; - fsp->oplock_type = e.op_type; - - if (fsp->oplock_type == LEASE_OPLOCK) { -@@ -760,21 +648,21 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, - */ - if (!GUID_equal(fsp_client_guid(fsp), - &e.client_guid)) { -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - -- status = leases_db_get( -+ state->status = leases_db_get( - &e.client_guid, - &e.lease_key, -- &file_id, -+ &fsp->file_id, - ¤t_state, /* current_state */ - NULL, /* breaking */ - NULL, /* breaking_to_requested */ - NULL, /* breaking_to_required */ - &lease_version, /* lease_version */ - &epoch); /* epoch */ -- if (!NT_STATUS_IS_OK(status)) { -+ if (!NT_STATUS_IS_OK(state->status)) { - goto fail; - } - -@@ -785,53 +673,46 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, - lease_version, - epoch); - if (fsp->lease == NULL) { -- status = NT_STATUS_NO_MEMORY; -+ state->status = NT_STATUS_NO_MEMORY; - goto fail; - } - } - -- fsp->initial_allocation_size = cookie.initial_allocation_size; -- fh_set_position_information(fsp->fh, cookie.position_information); -+ fsp->initial_allocation_size = state->cookie.initial_allocation_size; -+ fh_set_position_information(fsp->fh, state->cookie.position_information); - fsp->fsp_flags.update_write_time_triggered = -- cookie.update_write_time_triggered; -+ state->cookie.update_write_time_triggered; - fsp->fsp_flags.update_write_time_on_close = -- cookie.update_write_time_on_close; -- fsp->fsp_flags.write_time_forced = cookie.write_time_forced; -+ state->cookie.update_write_time_on_close; -+ fsp->fsp_flags.write_time_forced = state->cookie.write_time_forced; - fsp->close_write_time = nt_time_to_full_timespec( -- cookie.close_write_time); -+ state->cookie.close_write_time); - -- status = fsp_set_smb_fname(fsp, smb_fname); -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(0, ("vfs_default_durable_reconnect: " -- "fsp_set_smb_fname failed: %s\n", -- nt_errstr(status))); -- goto fail; -- } -- -- op->compat = fsp; -- fsp->op = op; -+ state->op->compat = fsp; -+ fsp->op = state->op; - - ok = reset_share_mode_entry( - lck, - e.pid, - e.share_file_id, -- messaging_server_id(conn->sconn->msg_ctx), -- smb1req->mid, -+ messaging_server_id(fsp->conn->sconn->msg_ctx), -+ state->smb1req->mid, - fh_get_gen_id(fsp->fh)); - if (!ok) { - DBG_DEBUG("Could not set new share_mode_entry values\n"); -- status = NT_STATUS_INTERNAL_ERROR; -+ state->status = NT_STATUS_INTERNAL_ERROR; - goto fail; - } - have_share_mode_entry = true; - -- ok = brl_reconnect_disconnected(fsp); -- if (!ok) { -- status = NT_STATUS_INTERNAL_ERROR; -- DEBUG(1, ("vfs_default_durable_reconnect: " -- "failed to reopen brlocks: %s\n", -- nt_errstr(status))); -- goto fail; -+ if (br_lck != NULL) { -+ ok = brl_reconnect_disconnected(fsp, br_lck); -+ if (!ok) { -+ state->status = NT_STATUS_INTERNAL_ERROR; -+ DBG_ERR("failed to reopen brlocks: %s\n", -+ nt_errstr(state->status)); -+ goto fail; -+ } - } - - /* -@@ -845,10 +726,9 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, - how.flags = O_RDONLY; - } - -- status = fd_openat(conn->cwd_fsp, fsp->fsp_name, fsp, &how); -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(1, ("vfs_default_durable_reconnect: failed to open " -- "file: %s\n", nt_errstr(status))); -+ state->status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, &how); -+ if (!NT_STATUS_IS_OK(state->status)) { -+ DBG_ERR("failed to open file: %s\n", nt_errstr(state->status)); - goto fail; - } - -@@ -863,70 +743,66 @@ NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, - - ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st); - if (ret == -1) { -- status = map_nt_error_from_unix_common(errno); -- DEBUG(1, ("Unable to fstat stream: %s => %s\n", -- smb_fname_str_dbg(smb_fname), -- nt_errstr(status))); -+ state->status = map_nt_error_from_unix_common(errno); -+ DBG_ERR("Unable to fstat stream: %s => %s\n", -+ fsp_str_dbg(fsp), -+ nt_errstr(state->status)); - goto fail; - } - - if (!S_ISREG(fsp->fsp_name->st.st_ex_mode)) { -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - -- file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st); -- if (!file_id_equal(&cookie.id, &file_id)) { -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ file_id = vfs_file_id_from_sbuf(fsp->conn, &fsp->fsp_name->st); -+ if (!file_id_equal(&state->cookie.id, &file_id)) { -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - - (void)fdos_mode(fsp); - -- ok = vfs_default_durable_reconnect_check_stat(&cookie.stat_info, -+ ok = vfs_default_durable_reconnect_check_stat(&state->cookie.stat_info, - &fsp->fsp_name->st, - fsp_str_dbg(fsp)); - if (!ok) { -- status = NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ state->status = NT_STATUS_OBJECT_NAME_NOT_FOUND; - goto fail; - } - -- status = set_file_oplock(fsp); -- if (!NT_STATUS_IS_OK(status)) { -+ state->status = set_file_oplock(fsp); -+ if (!NT_STATUS_IS_OK(state->status)) { - goto fail; - } - -- status = vfs_default_durable_cookie(fsp, mem_ctx, &new_cookie_blob); -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(1, ("vfs_default_durable_reconnect: " -- "vfs_default_durable_cookie - %s\n", -- nt_errstr(status))); -+ state->status = vfs_default_durable_cookie(fsp, -+ state->mem_ctx, -+ &state->new_cookie_blob); -+ if (!NT_STATUS_IS_OK(state->status)) { -+ DBG_ERR("vfs_default_durable_cookie - %s\n", -+ nt_errstr(state->status)); - goto fail; - } - -- smb1req->chain_fsp = fsp; -- smb1req->smb2req->compat_chain_fsp = fsp; -- -- DEBUG(10, ("vfs_default_durable_reconnect: opened file '%s'\n", -- fsp_str_dbg(fsp))); -+ state->smb1req->chain_fsp = fsp; -+ state->smb1req->smb2req->compat_chain_fsp = fsp; - -- TALLOC_FREE(lck); -+ DBG_DEBUG("opened file '%s'\n", fsp_str_dbg(fsp)); - - fsp->fsp_flags.is_fsa = true; - -- *result = fsp; -- *new_cookie = new_cookie_blob; -- -- return NT_STATUS_OK; -+ state->status = NT_STATUS_OK; -+ return; - - fail: -- if (fsp != NULL && have_share_mode_entry) { -+ if (have_share_mode_entry) { - /* - * Something is screwed up, delete the sharemode entry. - */ - del_share_mode(lck, fsp); - } -- if (fsp != NULL && fsp_get_pathref_fd(fsp) != -1) { -+ if (fsp_get_pathref_fd(fsp) != -1) { - NTSTATUS close_status; - close_status = fd_close(fsp); - if (!NT_STATUS_IS_OK(close_status)) { -@@ -934,11 +810,156 @@ fail: - nt_errstr(close_status)); - } - } -- TALLOC_FREE(lck); -- if (fsp != NULL) { -- op->compat = NULL; -- fsp->op = NULL; -- file_free(smb1req, fsp); -+ state->op->compat = NULL; -+ fsp->op = NULL; -+} -+ -+NTSTATUS vfs_default_durable_reconnect(struct connection_struct *conn, -+ struct smb_request *smb1req, -+ struct smbXsrv_open *op, -+ const DATA_BLOB old_cookie, -+ TALLOC_CTX *mem_ctx, -+ files_struct **result, -+ DATA_BLOB *new_cookie) -+{ -+ struct vfs_default_durable_reconnect_state state; -+ struct smb_filename *smb_fname = NULL; -+ struct file_id file_id; -+ NTSTATUS status; -+ enum ndr_err_code ndr_err; -+ int ret; -+ -+ *result = NULL; -+ *new_cookie = data_blob_null; -+ -+ if (!lp_durable_handles(SNUM(conn))) { -+ return NT_STATUS_NOT_SUPPORTED; -+ } -+ -+ state = (struct vfs_default_durable_reconnect_state) { -+ .mem_ctx = mem_ctx, -+ .smb1req = smb1req, -+ .op = op, -+ }; -+ -+ /* -+ * the checks for kernel oplocks -+ * and similar things are done -+ * in the vfs_default_durable_cookie() -+ * call below. -+ */ -+ -+ ndr_err = ndr_pull_struct_blob_all( -+ &old_cookie, -+ talloc_tos(), -+ &state.cookie, -+ (ndr_pull_flags_fn_t)ndr_pull_vfs_default_durable_cookie); -+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { -+ status = ndr_map_error2ntstatus(ndr_err); -+ return status; - } -- return status; -+ -+ if (strcmp(state.cookie.magic, VFS_DEFAULT_DURABLE_COOKIE_MAGIC) != 0) { -+ return NT_STATUS_INVALID_PARAMETER; -+ } -+ -+ if (state.cookie.version != VFS_DEFAULT_DURABLE_COOKIE_VERSION) { -+ return NT_STATUS_INVALID_PARAMETER; -+ } -+ -+ if (!state.cookie.allow_reconnect) { -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } -+ -+ if (strcmp(state.cookie.servicepath, conn->connectpath) != 0) { -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } -+ -+ /* Create an smb_filename with stream_name == NULL. */ -+ smb_fname = synthetic_smb_fname(talloc_tos(), -+ state.cookie.base_name, -+ NULL, -+ NULL, -+ 0, -+ 0); -+ if (smb_fname == NULL) { -+ return NT_STATUS_NO_MEMORY; -+ } -+ -+ ret = SMB_VFS_LSTAT(conn, smb_fname); -+ if (ret == -1) { -+ status = map_nt_error_from_unix_common(errno); -+ DEBUG(1, ("Unable to lstat stream: %s => %s\n", -+ smb_fname_str_dbg(smb_fname), -+ nt_errstr(status))); -+ return status; -+ } -+ if (!S_ISREG(smb_fname->st.st_ex_mode)) { -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } -+ -+ file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st); -+ if (!file_id_equal(&state.cookie.id, &file_id)) { -+ return NT_STATUS_OBJECT_NAME_NOT_FOUND; -+ } -+ -+ status = fsp_new(conn, conn, &state.fsp); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("failed to create new fsp: %s\n", -+ nt_errstr(status)); -+ return status; -+ } -+ state.fsp->file_id = file_id; -+ state.fsp->file_pid = smb1req->smbpid; -+ state.fsp->vuid = smb1req->vuid; -+ state.fsp->fnum = op->local_id; -+ fsp_set_gen_id(state.fsp); -+ -+ status = fsp_set_smb_fname(state.fsp, smb_fname); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("fsp_set_smb_fname failed: %s\n", -+ nt_errstr(status)); -+ file_free(smb1req, state.fsp); -+ return status; -+ } -+ -+ /* -+ * TODO: -+ * Do we need to store the modified flag in the DB? -+ */ -+ state.fsp->fsp_flags.modified = false; -+ /* -+ * no durables for directories -+ */ -+ state.fsp->fsp_flags.is_directory = false; -+ /* -+ * For normal files, can_lock == !is_directory -+ */ -+ state.fsp->fsp_flags.can_lock = true; -+ /* -+ * We do not support aio write behind for smb2 -+ */ -+ state.fsp->fsp_flags.aio_write_behind = false; -+ -+ status = share_mode_do_locked_brl(state.fsp, -+ vfs_default_durable_reconnect_fn, -+ &state); -+ if (!NT_STATUS_IS_OK(status)) { -+ DBG_ERR("share_mode_do_locked_brl [%s] failed: %s\n", -+ smb_fname_str_dbg(smb_fname), nt_errstr(status)); -+ file_free(smb1req, state.fsp); -+ return status; -+ } -+ if (!NT_STATUS_IS_OK(state.status)) { -+ DBG_ERR("default_durable_reconnect_fn [%s] failed: %s\n", -+ smb_fname_str_dbg(smb_fname), -+ nt_errstr(state.status)); -+ file_free(smb1req, state.fsp); -+ return state.status; -+ } -+ -+ *result = state.fsp; -+ *new_cookie = state.new_cookie_blob; -+ -+ return NT_STATUS_OK; - } --- -2.51.0 - - -From 810c9268742b761d3e32aedb624d343bdf51d467 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Tue, 28 Jan 2025 14:48:39 +0100 -Subject: [PATCH 24/43] s3:rpc_server/srvsvc: use brl_get_locks_readonly() - instead of brl_get_locks() - -No need to keep the record locked longer then needed. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767 - -Signed-off-by: Ralph Boehme -Reviewed-by: Stefan Metzmacher -(cherry picked from commit c36cc2b6720a2cfe54ce52a500dc499418e27e34) ---- - source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 12 +++++++++--- - 1 file changed, 9 insertions(+), 3 deletions(-) - -diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c -index 1129576f751..b19baf9e625 100644 ---- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c -+++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c -@@ -192,17 +192,23 @@ static WERROR net_enum_files(TALLOC_CTX *ctx, - /* need to count the number of locks on a file */ - - for (i=0; i<(*ctr3)->count; i++) { -- struct files_struct fsp = { .file_id = f_enum_cnt.fids[i], }; -+ struct files_struct *fsp = NULL; - struct byte_range_lock *brl = NULL; - -- brl = brl_get_locks(ctx, &fsp); -+ fsp = talloc_zero(talloc_tos(), struct files_struct); -+ if (fsp == NULL) { -+ return WERR_NOT_ENOUGH_MEMORY; -+ } -+ fsp->file_id = f_enum_cnt.fids[i]; -+ -+ brl = brl_get_locks_readonly(fsp); - if (brl == NULL) { - continue; - } - - (*ctr3)->array[i].num_locks = brl_num_locks(brl); -- - TALLOC_FREE(brl); -+ TALLOC_FREE(fsp); - } - - return WERR_OK; --- -2.51.0 - - -From 9dda09d94accbec2e7554ff5e5856e4e3f233780 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Wed, 16 Apr 2025 11:01:53 +0200 -Subject: [PATCH 25/43] third_party/socket_wrapper: SO_REUSEPORT is not - supported on a unix socket - ---- - third_party/socket_wrapper/socket_wrapper.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c -index 37799c82419..db20eac4ba2 100644 ---- a/third_party/socket_wrapper/socket_wrapper.c -+++ b/third_party/socket_wrapper/socket_wrapper.c -@@ -5110,6 +5110,13 @@ static int swrap_setsockopt(int s, int level, int optname, - } - - if (level == SOL_SOCKET) { -+ /* -+ * SO_REUSEPORT is not supported on a unix socket. glibc 2.40 -+ * returns ENOTSUPP now. -+ */ -+ if (optname == SO_REUSEPORT) { -+ return 0; -+ } - return libc_setsockopt(s, - level, - optname, --- -2.51.0 - - -From 8f08fd875e426d19418e7e2a3319f8b9fd5d86ee Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Tue, 14 Jan 2025 01:40:05 +0100 -Subject: [PATCH 26/43] s3-libads: dump ADS_MODSLIST before attempting the LDAP - modify - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15777 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider -(cherry picked from commit f02a4002d5c3cfcd7f36b3bcf13310ffd155de90) ---- - source3/libads/ldap.c | 66 +++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 66 insertions(+) - -diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c -index 6fad112ca00..a2654c1f504 100644 ---- a/source3/libads/ldap.c -+++ b/source3/libads/ldap.c -@@ -1968,6 +1968,67 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - return ADS_ERROR(LDAP_SUCCESS); - } - -+/* -+ dump a ADS_MODSLIST via DEBUG -+*/ -+static void ads_dump_modlist(ADS_MODLIST *mods) -+{ -+ LDAPMod **modlist = (LDAPMod **)*mods; -+ const char *op = NULL; -+ size_t i, j; -+ char *buf = NULL; -+ -+ if (mods == NULL || DEBUGLEVEL < DBGLVL_DEBUG) { -+ return; -+ } -+ -+ buf = talloc_strdup(talloc_tos(), ""); -+ -+ for (i = 0; modlist[i] != NULL; i++) { -+ -+ /* only ever used three ops */ -+ -+ switch (modlist[i]->mod_op) { -+ case LDAP_MOD_DELETE: -+ op = "LDAP_MOD_DELETE"; -+ break; -+ case LDAP_MOD_REPLACE: -+ op = "LDAP_MOD_REPLACE"; -+ break; -+ case LDAP_MOD_REPLACE | LDAP_MOD_BVALUES: -+ op = "LDAP_MOD_REPLACE | LDAP_MOD_BVALUES"; -+ break; -+ default: -+ op = "unknown"; -+ break; -+ } -+ -+ talloc_asprintf_addbuf(&buf, "mod[%zu]: mod_op: %s\n", i, op); -+ talloc_asprintf_addbuf(&buf, -+ "mod[%zu]: mod_type: %s\n", -+ i, -+ modlist[i]->mod_type); -+ -+ if (modlist[i]->mod_op & LDAP_MOD_BVALUES) { -+ continue; -+ } -+ -+ for (j = 0; modlist[i]->mod_values[j] != NULL; j++) { -+ talloc_asprintf_addbuf( -+ &buf, -+ "mod[%zu]: mod_values[%zu]: %s\n", -+ i, -+ j, -+ modlist[i]->mod_values[j]); -+ } -+ } -+ -+ if (buf != NULL) { -+ DBG_DEBUG("%s", buf); -+ TALLOC_FREE(buf); -+ } -+} -+ - /** - * Add a single string value to a mod list - * @param ctx An initialized TALLOC_CTX -@@ -2075,6 +2136,9 @@ ADS_STATUS ads_gen_mod(ADS_STRUCT *ads, const char *mod_dn, ADS_MODLIST mods) - for(i=0;(mods[i]!=0)&&(mods[i]!=(LDAPMod *) -1);i++); - /* make sure the end of the list is NULL */ - mods[i] = NULL; -+ -+ ads_dump_modlist(&mods); -+ - ret = ldap_modify_ext_s(ads->ldap.ld, utf8_dn, - (LDAPMod **) mods, controls, NULL); - ads_print_error(ret, ads->ldap.ld); -@@ -2107,6 +2171,8 @@ 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; - -+ ads_dump_modlist(&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); --- -2.51.0 - - -From 533e8f650e3aec632730d144f629a97e6fe37afc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Mon, 13 Jan 2025 20:26:01 +0100 -Subject: [PATCH 27/43] selfest: add test for non-local offlinejoin provision - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15777 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider -(cherry picked from commit 6d4ad4d6824e81ef85dd924d550222dd6a322a15) ---- - testprogs/blackbox/test_net_offline.sh | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/testprogs/blackbox/test_net_offline.sh b/testprogs/blackbox/test_net_offline.sh -index d885b337cea..e5b57e5431a 100755 ---- a/testprogs/blackbox/test_net_offline.sh -+++ b/testprogs/blackbox/test_net_offline.sh -@@ -34,6 +34,20 @@ samba_texpect="$BINDIR/texpect" - - netbios=$(grep "netbios name" $BASEDIR/$WORKDIR/client.conf | cut -f2 -d= | awk '{$1=$1};1') - -+# 0. Test with machine_name != lp_netbios_name() -+ -+NONLOCALMACHINE=win11 -+ -+testit "provision with non local machine name" \ -+ ${VALGRIND} ${net_tool} offlinejoin provision domain="${REALM}" machine_name="${NONLOCALMACHINE}" savefile="${ODJFILE}" -U"${DC_USERNAME}%${DC_PASSWORD}" || \ -+ failed=$((failed + 1)) -+ -+testit "net rpc user delete" \ -+ ${VALGRIND} ${net_tool} rpc user delete "${NONLOCALMACHINE}$" -U"${DC_USERNAME}%${DC_PASSWORD}" -S "${DC_SERVER}" || \ -+ failed=$((failed + 1)) -+ -+rm -f "${ODJFILE}" -+ - # 1. Test w/o dcname - - testit "provision without dcname" $VALGRIND $net_tool offlinejoin provision domain=$REALM machine_name=$netbios savefile=$ODJFILE -U$DC_USERNAME%$DC_PASSWORD || failed=$(expr $failed + 1) --- -2.51.0 - - -From acf26ab8f5cc1ab4aef98c00143a2ed21468d45d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Tue, 14 Jan 2025 19:16:31 +0100 -Subject: [PATCH 28/43] s3-libnet: avoid using lp_dns_hostname() in join code - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15777 - -This codepath is also used for provisiong non-local machines into AD -during offlinejoin operations. When creating accounts for non-local -machines we certainly need to be able to use arbitrary hostname other -than lp_netbios_name() (which is used internally by lp_dns_hostname()). -This partly reverts 0e96092c1895ecb41d4064111566b4ada71fe457. - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Thu Jan 30 07:35:05 UTC 2025 on atb-devel-224 - -(cherry picked from commit 062dc07e9b9c8e260548d0bca4d02819bdc60326) ---- - source3/libnet/libnet_join.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c -index d49d54436bb..f98d132d50f 100644 ---- a/source3/libnet/libnet_join.c -+++ b/source3/libnet/libnet_join.c -@@ -552,7 +552,14 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx, - * Register dns_hostname if needed, add_uniq_spn() will avoid - * duplicates. - */ -- dns_hostname = lp_dns_hostname(); -+ if (r->in.dnshostname != NULL) { -+ dns_hostname = talloc_strdup(frame, r->in.dnshostname); -+ } else { -+ dns_hostname = talloc_asprintf(frame, -+ "%s.%s", -+ r->in.machine_name, -+ r->out.dns_domain_name); -+ } - if (dns_hostname == NULL) { - status = ADS_ERROR_LDAP(LDAP_NO_MEMORY); - goto done; --- -2.51.0 - - -From 85ced19665fd27f1ab33b9bf9b971e640d3212ea Mon Sep 17 00:00:00 2001 -From: Stefan Metzmacher -Date: Fri, 11 Oct 2024 13:32:22 +0000 -Subject: [PATCH 29/43] s3:libsmb: let discover_dc_netbios() return - DOMAIN_CONTROLLER_NOT_FOUND - -We may get NT_STATUS_NOT_FOUND when the name can't be resolved -and NT_STATUS_INVALID_ADDRESS if the system doesn't have ipv4 -addresses... - -Signed-off-by: Stefan Metzmacher -Reviewed-by: Andreas Schneider -(cherry picked from commit e47ce1d10b13d8ef165c70984e6e490f4c2a64c2) ---- - source3/libsmb/dsgetdcname.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c -index 654893c172c..00e1fac6b93 100644 ---- a/source3/libsmb/dsgetdcname.c -+++ b/source3/libsmb/dsgetdcname.c -@@ -483,7 +483,19 @@ static NTSTATUS discover_dc_netbios(TALLOC_CTX *mem_ctx, - &count, - resolve_order); - if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10,("discover_dc_netbios: failed to find DC\n")); -+ NTSTATUS raw_status = status; -+ -+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { -+ status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; -+ } -+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_ADDRESS)) { -+ status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; -+ } -+ -+ DBG_DEBUG("failed to find DC for %s: %s => %s\n", -+ domain_name, -+ nt_errstr(raw_status), -+ nt_errstr(status)); - return status; - } - --- -2.51.0 - - -From 721eb10e2b2a409daac3b241b894ac2ebafd47f8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Wed, 2 Jul 2025 21:59:48 +0200 -Subject: [PATCH 30/43] s3-winbindd: Fix internal winbind dsgetdcname calls - w.r.t. domain name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -when winbind calls to dsgetdcname internally, make sure to -prefer the DNS domain name if we have it. Makes DNS lookups much more -likely to succeed. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider -Reviewed-by: Ralph Boehme - -Autobuild-User(master): Ralph Böhme -Autobuild-Date(master): Mon Jul 7 10:44:37 UTC 2025 on atb-devel-224 - -(cherry picked from commit 2560c9b3224816ffd371a62103f65b3aca301ad5) ---- - source3/winbindd/wb_queryuser.c | 17 +++++++++++++---- - source3/winbindd/wb_sids2xids.c | 17 +++++++++++++---- - source3/winbindd/wb_xids2sids.c | 12 +++++++++--- - source3/winbindd/winbindd_dual.c | 6 +++++- - source3/winbindd/winbindd_proto.h | 1 + - source3/winbindd/winbindd_util.c | 19 +++++++++++++++++++ - 6 files changed, 60 insertions(+), 12 deletions(-) - -diff --git a/source3/winbindd/wb_queryuser.c b/source3/winbindd/wb_queryuser.c -index c2758f1b76a..db8e946ba71 100644 ---- a/source3/winbindd/wb_queryuser.c -+++ b/source3/winbindd/wb_queryuser.c -@@ -289,10 +289,19 @@ static void wb_queryuser_done(struct tevent_req *subreq) - - if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) && - !state->tried_dclookup) { -- D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling wb_dsgetdcname_send()\n"); -- subreq = wb_dsgetdcname_send( -- state, state->ev, state->info->domain_name, NULL, NULL, -- DS_RETURN_DNS_NAME); -+ const char *domain_name = find_dns_domain_name( -+ state->info->domain_name); -+ -+ D_DEBUG("GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling " -+ "wb_dsgetdcname_send(%s)\n", -+ domain_name); -+ -+ subreq = wb_dsgetdcname_send(state, -+ state->ev, -+ domain_name, -+ NULL, -+ NULL, -+ DS_RETURN_DNS_NAME); - if (tevent_req_nomem(subreq, req)) { - return; - } -diff --git a/source3/winbindd/wb_sids2xids.c b/source3/winbindd/wb_sids2xids.c -index f0f6c23fc20..03e5e7e0258 100644 ---- a/source3/winbindd/wb_sids2xids.c -+++ b/source3/winbindd/wb_sids2xids.c -@@ -612,13 +612,22 @@ static void wb_sids2xids_done(struct tevent_req *subreq) - !state->tried_dclookup) { - - struct lsa_DomainInfo *d; -+ const char *domain_name = NULL; - -- D_DEBUG("Domain controller not found. Calling wb_dsgetdcname_send() to get it.\n"); - d = &state->idmap_doms.domains[state->dom_index]; - -- subreq = wb_dsgetdcname_send( -- state, state->ev, d->name.string, NULL, NULL, -- DS_RETURN_DNS_NAME); -+ domain_name = find_dns_domain_name(d->name.string); -+ -+ D_DEBUG("Domain controller not found. Calling " -+ "wb_dsgetdcname_send(%s) to get it.\n", -+ domain_name); -+ -+ subreq = wb_dsgetdcname_send(state, -+ state->ev, -+ domain_name, -+ NULL, -+ NULL, -+ DS_RETURN_DNS_NAME); - if (tevent_req_nomem(subreq, req)) { - return; - } -diff --git a/source3/winbindd/wb_xids2sids.c b/source3/winbindd/wb_xids2sids.c -index 86bd7f9deab..6fcf524d94f 100644 ---- a/source3/winbindd/wb_xids2sids.c -+++ b/source3/winbindd/wb_xids2sids.c -@@ -143,9 +143,15 @@ static void wb_xids2sids_dom_done(struct tevent_req *subreq) - if (NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) && - !state->tried_dclookup) { - -- subreq = wb_dsgetdcname_send( -- state, state->ev, state->dom_map->name, NULL, NULL, -- DS_RETURN_DNS_NAME); -+ const char *domain_name = find_dns_domain_name( -+ state->dom_map->name); -+ -+ subreq = wb_dsgetdcname_send(state, -+ state->ev, -+ domain_name, -+ NULL, -+ NULL, -+ DS_RETURN_DNS_NAME); - if (tevent_req_nomem(subreq, req)) { - return; - } -diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c -index c27fa2653f2..6570c3dec23 100644 ---- a/source3/winbindd/winbindd_dual.c -+++ b/source3/winbindd/winbindd_dual.c -@@ -532,6 +532,7 @@ static void wb_domain_request_trigger(struct tevent_req *req, - struct wb_domain_request_state *state = tevent_req_data( - req, struct wb_domain_request_state); - struct winbindd_domain *domain = state->domain; -+ const char *domain_name = NULL; - struct tevent_req *subreq = NULL; - size_t shortest_queue_length; - -@@ -604,8 +605,11 @@ static void wb_domain_request_trigger(struct tevent_req *req, - * which is indicated by DS_RETURN_DNS_NAME. - * For NT4 domains we still get the netbios name. - */ -+ -+ domain_name = find_dns_domain_name(state->domain->name); -+ - subreq = wb_dsgetdcname_send(state, state->ev, -- state->domain->name, -+ domain_name, - NULL, /* domain_guid */ - NULL, /* site_name */ - DS_RETURN_DNS_NAME); /* flags */ -diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h -index 5b90a7a731f..e318911d192 100644 ---- a/source3/winbindd/winbindd_proto.h -+++ b/source3/winbindd/winbindd_proto.h -@@ -610,6 +610,7 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, - struct dom_sid **sids, uint32_t *num_sids); - bool parse_xidlist(TALLOC_CTX *mem_ctx, const char *xidstr, - struct unixid **pxids, uint32_t *pnum_xids); -+const char *find_dns_domain_name(const char *domain_name); - - /* The following definitions come from winbindd/winbindd_wins.c */ - -diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c -index 2234efeed54..c94d313e9fd 100644 ---- a/source3/winbindd/winbindd_util.c -+++ b/source3/winbindd/winbindd_util.c -@@ -2241,3 +2241,22 @@ fail: - TALLOC_FREE(xids); - return false; - } -+ -+/** -+ * Helper to extract the DNS Domain Name from a struct winbindd_domain -+ */ -+const char *find_dns_domain_name(const char *domain_name) -+{ -+ struct winbindd_domain *wbdom = NULL; -+ -+ wbdom = find_domain_from_name(domain_name); -+ if (wbdom == NULL) { -+ return domain_name; -+ } -+ -+ if (wbdom->active_directory && wbdom->alt_name != NULL) { -+ return wbdom->alt_name; -+ } -+ -+ return wbdom->name; -+} --- -2.51.0 - - -From ea989a77c0f55b6be75cc274b351b9745fdb52f1 Mon Sep 17 00:00:00 2001 -From: Stefan Metzmacher -Date: Fri, 9 May 2025 09:38:41 +0200 -Subject: [PATCH 31/43] s3:winbindd: avoid using any netlogon call to get a dc - name - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876 - -Signed-off-by: Stefan Metzmacher -Reviewed-by: Guenther Deschner -Reviewed-by: Andreas Schneider -Reviewed-by: Ralph Boehme -(cherry picked from commit f86a4bf6848ade2db7229d182576db3320c3ece7) ---- - source3/winbindd/winbindd_cm.c | 150 --------------------------- - source3/winbindd/winbindd_dual_srv.c | 105 +------------------ - 2 files changed, 5 insertions(+), 250 deletions(-) - -diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c -index f33e0bcb165..602f81ad621 100644 ---- a/source3/winbindd/winbindd_cm.c -+++ b/source3/winbindd/winbindd_cm.c -@@ -475,140 +475,6 @@ static bool cm_is_ipc_credentials(struct cli_credentials *creds) - return ret; - } - --static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, -- fstring dcname, -- struct sockaddr_storage *dc_ss, -- uint32_t request_flags) --{ -- struct winbindd_domain *our_domain = NULL; -- struct rpc_pipe_client *netlogon_pipe = NULL; -- NTSTATUS result; -- WERROR werr; -- TALLOC_CTX *mem_ctx; -- unsigned int orig_timeout; -- const char *tmp = NULL; -- const char *p; -- struct dcerpc_binding_handle *b; -- -- /* Hmmmm. We can only open one connection to the NETLOGON pipe at the -- * moment.... */ -- -- if (IS_DC) { -- return False; -- } -- -- if (domain->primary) { -- return False; -- } -- -- our_domain = find_our_domain(); -- -- if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) { -- return False; -- } -- -- result = cm_connect_netlogon(our_domain, &netlogon_pipe); -- if (!NT_STATUS_IS_OK(result)) { -- talloc_destroy(mem_ctx); -- return False; -- } -- -- b = netlogon_pipe->binding_handle; -- -- /* This call can take a long time - allow the server to time out. -- 35 seconds should do it. */ -- -- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); -- -- if (our_domain->active_directory) { -- struct netr_DsRGetDCNameInfo *domain_info = NULL; -- -- /* -- * TODO request flags are not respected in the server -- * (and in some cases, like REQUIRE_PDC, causes an error) -- */ -- result = dcerpc_netr_DsRGetDCName(b, -- mem_ctx, -- our_domain->dcname, -- domain->name, -- NULL, -- NULL, -- request_flags|DS_RETURN_DNS_NAME, -- &domain_info, -- &werr); -- if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) { -- tmp = talloc_strdup( -- mem_ctx, domain_info->dc_unc); -- if (tmp == NULL) { -- DBG_ERR("talloc_strdup failed for dc_unc[%s]\n", -- domain_info->dc_unc); -- talloc_destroy(mem_ctx); -- return false; -- } -- if (domain->alt_name == NULL) { -- domain->alt_name = talloc_strdup(domain, -- domain_info->domain_name); -- if (domain->alt_name == NULL) { -- DBG_ERR("talloc_strdup failed for " -- "domain_info->domain_name[%s]\n", -- domain_info->domain_name); -- talloc_destroy(mem_ctx); -- return false; -- } -- } -- if (domain->forest_name == NULL) { -- domain->forest_name = talloc_strdup(domain, -- domain_info->forest_name); -- if (domain->forest_name == NULL) { -- DBG_ERR("talloc_strdup failed for " -- "domain_info->forest_name[%s]\n", -- domain_info->forest_name); -- talloc_destroy(mem_ctx); -- return false; -- } -- } -- } -- } else { -- result = dcerpc_netr_GetAnyDCName(b, mem_ctx, -- our_domain->dcname, -- domain->name, -- &tmp, -- &werr); -- } -- -- /* And restore our original timeout. */ -- rpccli_set_timeout(netlogon_pipe, orig_timeout); -- -- if (!NT_STATUS_IS_OK(result)) { -- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n", -- nt_errstr(result))); -- talloc_destroy(mem_ctx); -- return false; -- } -- -- if (!W_ERROR_IS_OK(werr)) { -- DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n", -- win_errstr(werr))); -- talloc_destroy(mem_ctx); -- return false; -- } -- -- /* dcerpc_netr_GetAnyDCName gives us a name with \\ */ -- p = strip_hostname(tmp); -- -- fstrcpy(dcname, p); -- -- talloc_destroy(mem_ctx); -- -- DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname)); -- -- if (!resolve_name(dcname, dc_ss, 0x20, true)) { -- return False; -- } -- -- return True; --} -- - /** - * Helper function to assemble trust password and account name - */ -@@ -1298,24 +1164,8 @@ static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain, - struct samba_sockaddr *sa_list = NULL; - size_t salist_size = 0; - size_t i; -- bool is_our_domain; - enum security_types sec = (enum security_types)lp_security(); - -- is_our_domain = strequal(domain->name, lp_workgroup()); -- -- /* If not our domain, get the preferred DC, by asking our primary DC */ -- if ( !is_our_domain -- && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags) -- && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs, -- num_dcs) ) -- { -- char addr[INET6_ADDRSTRLEN]; -- print_sockaddr(addr, sizeof(addr), &ss); -- DEBUG(10, ("Retrieved DC %s at %s via netlogon\n", -- dcname, addr)); -- return True; -- } -- - if ((sec == SEC_ADS) && (domain->alt_name != NULL)) { - char *sitename = NULL; - -diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c -index 0c7e9dd5491..4f855d424e5 100644 ---- a/source3/winbindd/winbindd_dual_srv.c -+++ b/source3/winbindd/winbindd_dual_srv.c -@@ -662,106 +662,11 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p, - - NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r) - { -- struct winbindd_domain *domain = wb_child_domain(); -- struct rpc_pipe_client *netlogon_pipe; -- struct netr_DsRGetDCNameInfo *dc_info; -- NTSTATUS status; -- WERROR werr; -- unsigned int orig_timeout; -- struct dcerpc_binding_handle *b; -- bool retry = false; -- bool try_dsrgetdcname = false; -- -- if (domain == NULL) { -- return dsgetdcname(p->mem_ctx, global_messaging_context(), -- r->in.domain_name, r->in.domain_guid, -- r->in.site_name ? r->in.site_name : "", -- r->in.flags, -- r->out.dc_info); -- } -- -- if (domain->active_directory) { -- try_dsrgetdcname = true; -- } -- --reconnect: -- status = cm_connect_netlogon(domain, &netlogon_pipe); -- -- reset_cm_connection_on_error(domain, NULL, status); -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10, ("Can't contact the NETLOGON pipe\n")); -- return status; -- } -- -- b = netlogon_pipe->binding_handle; -- -- /* This call can take a long time - allow the server to time out. -- 35 seconds should do it. */ -- -- orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000); -- -- if (try_dsrgetdcname) { -- status = dcerpc_netr_DsRGetDCName(b, -- p->mem_ctx, domain->dcname, -- r->in.domain_name, NULL, r->in.domain_guid, -- r->in.flags, r->out.dc_info, &werr); -- if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(werr)) { -- goto done; -- } -- if (!retry && -- reset_cm_connection_on_error(domain, NULL, status)) -- { -- retry = true; -- goto reconnect; -- } -- try_dsrgetdcname = false; -- retry = false; -- } -- -- /* -- * Fallback to less capable methods -- */ -- -- dc_info = talloc_zero(r->out.dc_info, struct netr_DsRGetDCNameInfo); -- if (dc_info == NULL) { -- status = NT_STATUS_NO_MEMORY; -- goto done; -- } -- -- if (r->in.flags & DS_PDC_REQUIRED) { -- status = dcerpc_netr_GetDcName(b, -- p->mem_ctx, domain->dcname, -- r->in.domain_name, &dc_info->dc_unc, &werr); -- } else { -- status = dcerpc_netr_GetAnyDCName(b, -- p->mem_ctx, domain->dcname, -- r->in.domain_name, &dc_info->dc_unc, &werr); -- } -- -- if (!retry && reset_cm_connection_on_error(domain, b, status)) { -- retry = true; -- goto reconnect; -- } -- if (!NT_STATUS_IS_OK(status)) { -- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n", -- nt_errstr(status))); -- goto done; -- } -- if (!W_ERROR_IS_OK(werr)) { -- DEBUG(10, ("dcerpc_netr_Get[Any]DCName failed: %s\n", -- win_errstr(werr))); -- status = werror_to_ntstatus(werr); -- goto done; -- } -- -- *r->out.dc_info = dc_info; -- status = NT_STATUS_OK; -- --done: -- /* And restore our original timeout. */ -- rpccli_set_timeout(netlogon_pipe, orig_timeout); -- -- return status; -+ return dsgetdcname(p->mem_ctx, global_messaging_context(), -+ r->in.domain_name, r->in.domain_guid, -+ r->in.site_name ? r->in.site_name : "", -+ r->in.flags, -+ r->out.dc_info); - } - - NTSTATUS _wbint_LookupRids(struct pipes_struct *p, struct wbint_LookupRids *r) --- -2.51.0 - - -From e4b8f235c45054cd3a29a9a54b2f835fce3fcdd3 Mon Sep 17 00:00:00 2001 -From: Aleksandr Sharov -Date: Fri, 4 Jul 2025 15:32:28 +0200 -Subject: [PATCH 32/43] Add check for the GPO link to have at least two - attributes separated by semicolumn. Allows to handle empty links. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15877 -RN: Fix handling of empty GPO link - -Singed-off-by: Alex Sharov (kororland@gmail.com) -Reviewed-by: Douglas Bagnall -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Thu Jul 10 18:55:33 UTC 2025 on atb-devel-224 - -(cherry picked from commit 44ee31c0258b0afb3d3f2ce17942cc86e308a690) ---- - python/samba/gp/gpclass.py | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/python/samba/gp/gpclass.py b/python/samba/gp/gpclass.py -index d86aacec138..07b4fb3e7bd 100644 ---- a/python/samba/gp/gpclass.py -+++ b/python/samba/gp/gpclass.py -@@ -673,8 +673,10 @@ class GP_LINK: - self.gp_opts = int(gPOptions) - - def gpo_parse_gplink(self, gPLink): -+ # normally formed link looks like [LDAP://host/path;options] -+ # empty link looks like [ ] - for p in gPLink.decode().split(']'): -- if not p: -+ if not p or ';' not in p: - continue - log.debug('gpo_parse_gplink: processing link') - p = p.lstrip('[') --- -2.51.0 - - -From 683da4a43c1fc8ffabd44dbf829a6cb20ab93057 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?G=C3=BCnther=20Deschner?= -Date: Sun, 20 Jul 2025 17:59:37 +0200 -Subject: [PATCH 33/43] s3-selftest: add tests for "net ads kerberos" commands - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15840 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider -(cherry picked from commit 18d0574a0fe4b5fd468f949cfaa507ab4519c9e6) ---- - selftest/knownfail | 3 + - source3/script/tests/test_net_ads_kerberos.sh | 158 ++++++++++++++++++ - source3/selftest/tests.py | 12 ++ - 3 files changed, 173 insertions(+) - create mode 100755 source3/script/tests/test_net_ads_kerberos.sh - -diff --git a/selftest/knownfail b/selftest/knownfail -index 5f64e4edad0..802567c2404 100644 ---- a/selftest/knownfail -+++ b/selftest/knownfail -@@ -344,3 +344,6 @@ - # We currently don't send referrals for LDAP modify of non-replicated attrs - ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* - -+# net ads kerberos -+samba3.blackbox.net_ads_kerberos.*net_ads_kerberos_kinit.* -+samba3.blackbox.net_ads_kerberos.*net_ads_kerberos_renew.* -diff --git a/source3/script/tests/test_net_ads_kerberos.sh b/source3/script/tests/test_net_ads_kerberos.sh -new file mode 100755 -index 00000000000..8a3c9ef2bc7 ---- /dev/null -+++ b/source3/script/tests/test_net_ads_kerberos.sh -@@ -0,0 +1,158 @@ -+#!/bin/sh -+ -+if [ $# -lt 5 ]; then -+ cat < -Date: Sun, 20 Jul 2025 18:00:22 +0200 -Subject: [PATCH 34/43] s3-net: fix "net ads kerberos" krb5ccname handling -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We can only rely on KRB5CCNAME being set, --use-krb5-ccname content is -not available. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15840 - -Guenther - -Signed-off-by: Guenther Deschner -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Günther Deschner -Autobuild-Date(master): Thu Jul 24 17:31:14 UTC 2025 on atb-devel-224 - -(cherry picked from commit 8a97afdae788e8d10a51035f8b287dc00293f90d) ---- - selftest/knownfail | 4 ---- - source3/utils/net.c | 15 +++++++++++++++ - source3/utils/net.h | 1 + - source3/utils/net_ads.c | 6 +++--- - 4 files changed, 19 insertions(+), 7 deletions(-) - -diff --git a/selftest/knownfail b/selftest/knownfail -index 802567c2404..a7a2e2b2251 100644 ---- a/selftest/knownfail -+++ b/selftest/knownfail -@@ -343,7 +343,3 @@ - - # We currently don't send referrals for LDAP modify of non-replicated attrs - ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* -- --# net ads kerberos --samba3.blackbox.net_ads_kerberos.*net_ads_kerberos_kinit.* --samba3.blackbox.net_ads_kerberos.*net_ads_kerberos_renew.* -diff --git a/source3/utils/net.c b/source3/utils/net.c -index c432ebe991f..7ce93ced79e 100644 ---- a/source3/utils/net.c -+++ b/source3/utils/net.c -@@ -1394,6 +1394,7 @@ static struct functable net_func[] = { - cli_credentials_get_principal_obtained(c->creds); - enum credentials_obtained password_obtained = - cli_credentials_get_password_obtained(c->creds); -+ char *krb5ccname = NULL; - - if (principal_obtained == CRED_SPECIFIED) { - c->explicit_credentials = true; -@@ -1410,6 +1411,20 @@ static struct functable net_func[] = { - GENSEC_FEATURE_NTLM_CCACHE, - CRED_SPECIFIED); - } -+ -+ /* cli_credentials_get_ccache_name_obtained() would not work -+ * here, we also cannot get the content of --use-krb5-ccache= so -+ * for now at least honour the KRB5CCNAME environment variable -+ * to get 'net ads kerberos' functions to work at all - gd */ -+ -+ krb5ccname = getenv("KRB5CCNAME"); -+ if (krb5ccname == NULL) { -+ krb5ccname = talloc_strdup(c, "MEMORY:net"); -+ } -+ if (krb5ccname == NULL) { -+ exit(1); -+ } -+ c->opt_krb5_ccache = krb5ccname; - } - - c->msg_ctx = cmdline_messaging_context(get_dyn_CONFIGFILE()); -diff --git a/source3/utils/net.h b/source3/utils/net.h -index 8540a6db9d4..8a4218b529f 100644 ---- a/source3/utils/net.h -+++ b/source3/utils/net.h -@@ -97,6 +97,7 @@ struct net_context { - const char *opt_witness_new_ip; - int opt_witness_new_node; - const char *opt_witness_forced_response; -+ const char *opt_krb5_ccache; - - int opt_have_ip; - struct sockaddr_storage opt_dest_ip; -diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c -index 0e5da492faf..394a65d9a59 100644 ---- a/source3/utils/net_ads.c -+++ b/source3/utils/net_ads.c -@@ -3041,7 +3041,7 @@ static int net_ads_kerberos_renew(struct net_context *c, int argc, const char ** - return -1; - } - -- ret = smb_krb5_renew_ticket(NULL, NULL, NULL, NULL); -+ ret = smb_krb5_renew_ticket(c->opt_krb5_ccache, NULL, NULL, NULL); - if (ret) { - d_printf(_("failed to renew kerberos ticket: %s\n"), - error_message(ret)); -@@ -3096,7 +3096,7 @@ static int net_ads_kerberos_pac_common(struct net_context *c, int argc, const ch - 0, - NULL, - NULL, -- NULL, -+ c->opt_krb5_ccache, - true, - true, - 2592000, /* one month */ -@@ -3277,7 +3277,7 @@ static int net_ads_kerberos_kinit(struct net_context *c, int argc, const char ** - 0, - NULL, - NULL, -- NULL, -+ c->opt_krb5_ccache, - true, - true, - 2592000, /* one month */ --- -2.51.0 - - -From d5f1752f88264d39bfb9bc2532d1d005e797aaf9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Wed, 23 Jul 2025 15:09:21 +0200 -Subject: [PATCH 35/43] s3:winbindd: Resolve dc name using CLDAP also for - ROLE_IPA_DC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -server role ROLE_IPA_DC (introduced in e2d5b4d) needs special handling -in dcip_check_name(). We should resolve the DC name using: -- CLDAP in dcip_check_name_ads() -instead of: -- NETBIOS in nbt_getdc() that fails if Windows is not providing netbios. - -The impacted environment has: - -domain->alt_name = example.com -domain->active_directory = 1 -security = USER -server role = ROLE_IPA_DC - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15891 - -Signed-off-by: Pavel Filipenský -Signed-off-by: Andreas Schneider -Pair-programmed-with: Andreas Schneider - -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 4921c3304e5e0480e5bb80a757b3f04b3b92c3b1) -(cherry picked from commit fe8eafc289dfbb6f2b6c706f2a8a68186807d4f8) ---- - source3/winbindd/winbindd_cm.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c -index 602f81ad621..95438d6cebc 100644 ---- a/source3/winbindd/winbindd_cm.c -+++ b/source3/winbindd/winbindd_cm.c -@@ -1089,7 +1089,9 @@ static bool dcip_check_name(TALLOC_CTX *mem_ctx, - - if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) { - is_ad_domain = true; -- } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { -+ } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || -+ lp_server_role() == ROLE_IPA_DC) -+ { - is_ad_domain = domain->active_directory; - } - --- -2.51.0 - - -From c5c6536e41d07b8a3d54d7159e44cbf2d8db22f2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Mon, 4 Aug 2025 08:35:29 +0200 -Subject: [PATCH 36/43] docs-xml: Make smb.conf 'server role' value consistent - with ROLE_IPA_DC in libparam -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15891 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Alexander Bokovoy -Reviewed-by: Andreas Schneider -(cherry picked from commit d88268102ade07fab345e04109818d97d8843a14) -(cherry picked from commit d14fa6eb96a9f296d386ff4864e4f016440f2ac8) ---- - docs-xml/smbdotconf/security/serverrole.xml | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/docs-xml/smbdotconf/security/serverrole.xml b/docs-xml/smbdotconf/security/serverrole.xml -index 4ea4e4751ee..40244e125ce 100644 ---- a/docs-xml/smbdotconf/security/serverrole.xml -+++ b/docs-xml/smbdotconf/security/serverrole.xml -@@ -78,7 +78,7 @@ - url="http://wiki.samba.org/index.php/Samba4/HOWTO">Samba4 - HOWTO - -- SERVER ROLE = IPA DOMAIN CONTROLLER -+ SERVER ROLE = IPA PRIMARY DOMAIN CONTROLLER - - This mode of operation runs Samba in a hybrid mode for IPA - domain controller, providing forest trust to Active Directory. --- -2.51.0 - - -From c3f3ffa897890ebf0bceaff2fd50ff03d978b336 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Mon, 4 Aug 2025 23:26:02 +0200 -Subject: [PATCH 37/43] s3:netlogon: IPA DC is the PDC as well - allow - ROLE_IPA_DC in _netr_DsRGetForestTrustInformation() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15891 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Alexander Bokovoy -Reviewed-by: Andreas Schneider -(cherry picked from commit 1dbafcc4e4ff8f39af5ca737b30e9821413dd1f2) -(cherry picked from commit 00adb3104e745babb2c330fa9c9e324805395edb) ---- - source3/rpc_server/netlogon/srv_netlog_nt.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c -index 2ba16d423e3..613269824d6 100644 ---- a/source3/rpc_server/netlogon/srv_netlog_nt.c -+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c -@@ -2655,7 +2655,10 @@ WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p, - return WERR_INVALID_FLAGS; - } - -- if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) { -+ if ((r->in.flags & DS_GFTI_UPDATE_TDO) && -+ (lp_server_role() != ROLE_DOMAIN_PDC) && -+ (lp_server_role() != ROLE_IPA_DC)) -+ { - p->fault_state = DCERPC_FAULT_OP_RNG_ERROR; - return WERR_NERR_NOTPRIMARY; - } --- -2.51.0 - - -From dac03d657380df79111ef642bc8e9ea9091f1a59 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Mon, 4 Aug 2025 23:28:24 +0200 -Subject: [PATCH 38/43] s3:utils: Allow ROLE_IPA_DC to allow to use Kerberos in - gensec -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15891 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Alexander Bokovoy -Reviewed-by: Andreas Schneider - -Autobuild-User(master): Andreas Schneider -Autobuild-Date(master): Tue Aug 5 14:51:51 UTC 2025 on atb-devel-224 - -(cherry picked from commit a4dff82e45308db3ccabac2a55c03d52f04d7b4d) - -Autobuild-User(v4-22-test): Jule Anger -Autobuild-Date(v4-22-test): Mon Aug 11 07:53:47 UTC 2025 on atb-devel-224 - -(cherry picked from commit 3364797676624aa9367076a69b2daf73870429ba) ---- - source3/utils/ntlm_auth.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c -index e9b644724d9..df1484ecd21 100644 ---- a/source3/utils/ntlm_auth.c -+++ b/source3/utils/ntlm_auth.c -@@ -1355,7 +1355,11 @@ static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx, - - cli_credentials_set_conf(server_credentials, lp_ctx); - -- if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) { -+ if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || -+ lp_server_role() == ROLE_IPA_DC || -+ lp_security() == SEC_ADS || -+ USE_KERBEROS_KEYTAB) -+ { - cli_credentials_set_kerberos_state(server_credentials, - CRED_USE_KERBEROS_DESIRED, - CRED_SPECIFIED); --- -2.51.0 - - -From 5e745666e306a8a39d6953df9c60a2ba49810bfa Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Tue, 22 Jul 2025 19:22:31 +0200 -Subject: [PATCH 39/43] libads: fix get_kdc_ip_string() - -Correctly handle the interaction between optionally passed in DC via -pss and DC lookup. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876 - -Signed-off-by: Ralph Boehme -Reviewed-by: Guenther Deschner -(backported with some changes from commit 23f100f67c0586a940e91e9e1e6f42b804401322) ---- - source3/libads/kerberos.c | 15 ++++++++++++--- - 1 file changed, 12 insertions(+), 3 deletions(-) - -diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c -index 72ce5b7bb34..e0d8fe689d4 100644 ---- a/source3/libads/kerberos.c -+++ b/source3/libads/kerberos.c -@@ -531,10 +531,12 @@ static char *get_kdc_ip_string(char *mem_ctx, - DBG_DEBUG("%zu additional KDCs to test\n", num_dcs); - if (num_dcs == 0) { - /* -- * We do not have additional KDCs, but we have the one passed -- * in via `pss`. So just use that one and leave. -+ * We do not have additional KDCs, but if we have one passed -+ * in via `pss` just use that one, otherwise fail - */ -- result = talloc_move(mem_ctx, &kdc_str); -+ if (pss != NULL) { -+ result = talloc_move(mem_ctx, &kdc_str); -+ } - goto out; - } - -@@ -575,6 +577,13 @@ static char *get_kdc_ip_string(char *mem_ctx, - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: " - "%s\n", nt_errstr(status))); -+ /* -+ * cldap_multi_netlogon() failed, but if we have one passed -+ * in via `pss` just just use that one, otherwise fail -+ */ -+ if (pss != NULL) { -+ result = talloc_move(mem_ctx, &kdc_str); -+ } - goto out; - } - --- -2.51.0 - - -From 49de00806ca9a31f838bb638592a544935540fa2 Mon Sep 17 00:00:00 2001 -From: Ralph Boehme -Date: Tue, 22 Jul 2025 19:16:14 +0200 -Subject: [PATCH 40/43] winbindd: use find_domain_from_name_noinit() in - find_dns_domain_name() - -Avoid triggering a connection to a DC of a trusted domain. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15876 - -Signed-off-by: Ralph Boehme -Reviewed-by: Guenther Deschner -(cherry picked from commit 9ad2e59a464bb472da2071c61a254547b6497625) ---- - source3/winbindd/winbindd_util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c -index c94d313e9fd..79ed3f55423 100644 ---- a/source3/winbindd/winbindd_util.c -+++ b/source3/winbindd/winbindd_util.c -@@ -2249,7 +2249,7 @@ const char *find_dns_domain_name(const char *domain_name) - { - struct winbindd_domain *wbdom = NULL; - -- wbdom = find_domain_from_name(domain_name); -+ wbdom = find_domain_from_name_noinit(domain_name); - if (wbdom == NULL) { - return domain_name; - } --- -2.51.0 - - -From 7d0cb7446237e8058c916b523ebe588825744f86 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Tue, 29 Jul 2025 11:19:07 +0200 -Subject: [PATCH 41/43] selftest: Add the short name for localvampiredc to - hosts file -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Alexander Bokovoy -(cherry picked from commit 5d2f60ae5aa96751b74901ae5384291ef338b152) ---- - selftest/target/Samba4.pm | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm -index e917f65fc36..1a86f7a07d5 100755 ---- a/selftest/target/Samba4.pm -+++ b/selftest/target/Samba4.pm -@@ -869,7 +869,7 @@ nogroup:x:65534:nobody - - my $hostname = lc($ctx->{hostname}); - open(HOSTS, ">>$ctx->{nsswrap_hosts}"); -- if ($hostname eq "localdc") { -+ if ($hostname eq "localdc" || $hostname eq "localvampiredc") { - print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; - print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; - } else { --- -2.51.0 - - -From 915e0029ce8b476c15408fba5a74a8d32a80c2c5 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= -Date: Mon, 4 Aug 2025 11:20:54 +0200 -Subject: [PATCH 42/43] tests: Add test for 'net ads join' to a preferred DC -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 - -Signed-off-by: Pavel Filipenský -Reviewed-by: Alexander Bokovoy -(backported from commit 36f6ac547c09f492d1dcab11570e8bcbd377cf26) ---- - selftest/knownfail | 1 + - source4/selftest/tests.py | 1 + - .../test_net_ads_join_to_preferred_dc.sh | 61 +++++++++++++++++++ - 3 files changed, 63 insertions(+) - create mode 100755 testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh - -diff --git a/selftest/knownfail b/selftest/knownfail -index a7a2e2b2251..94d9ffc5fcb 100644 ---- a/selftest/knownfail -+++ b/selftest/knownfail -@@ -340,6 +340,7 @@ - ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.* - ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dbcheck_dangling_multi_valued_clean - ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing -+^samba4.blackbox.net_ads_join.join - - # We currently don't send referrals for LDAP modify of non-replicated attrs - ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* -diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py -index 3b046c27a28..a77a3d8f780 100755 ---- a/source4/selftest/tests.py -+++ b/source4/selftest/tests.py -@@ -897,6 +897,7 @@ plantestsuite("samba4.blackbox.rfc2307_mapping", - plantestsuite("samba4.blackbox.chgdcpass", "chgdcpass", [os.path.join(bbdir, "test_chgdcpass.sh"), '$SERVER', r"CHGDCPASS\$", '$REALM', '$DOMAIN', '$PREFIX/chgdcpass', "aes256-cts-hmac-sha1-96", '$PREFIX/chgdcpass', smbclient3]) - plantestsuite("samba4.blackbox.samba_upgradedns(chgdcpass:local)", "chgdcpass:local", [os.path.join(bbdir, "test_samba_upgradedns.sh"), '$SERVER', '$REALM', '$PREFIX', '$SELFTEST_PREFIX/chgdcpass']) - plantestsuite("samba4.blackbox.net_ads", "ad_dc:client", [os.path.join(bbdir, "test_net_ads.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) -+plantestsuite("samba4.blackbox.net_ads_join", "vampire_dc:client", [os.path.join(bbdir, "test_net_ads_join_to_preferred_dc.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX']) - plantestsuite("samba4.blackbox.net_offlinejoin", "ad_dc:client", [os.path.join(bbdir, "test_net_offline.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) - plantestsuite("samba4.blackbox.client_etypes_all(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'all', '17_18_23']) - plantestsuite("samba4.blackbox.client_etypes_legacy(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'legacy', '23']) -diff --git a/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh -new file mode 100755 -index 00000000000..1bebc2f4dbe ---- /dev/null -+++ b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh -@@ -0,0 +1,61 @@ -+if [ $# -lt 4 ]; then -+ cat </dev/null | sha1sum | cut -b 1-10) -+ -+RUNDIR=$(pwd) -+cd $BASEDIR -+WORKDIR=$(mktemp -d -p .) -+WORKDIR=$(basename $WORKDIR) -+cp -a client/* $WORKDIR/ -+sed -ri "s@(dir|directory) = (.*)/client/@\1 = \2/$WORKDIR/@" $WORKDIR/client.conf -+sed -ri "s/netbios name = .*/netbios name = $HOSTNAME/" $WORKDIR/client.conf -+rm -f $WORKDIR/private/secrets.tdb -+cd $RUNDIR -+ -+failed=0 -+ -+net_tool="$BINDIR/net --configfile=$BASEDIR/$WORKDIR/client.conf --option=security=ads" -+ -+# Load test functions -+. $(dirname $0)/subunit.sh -+. "$(dirname "${0}")/common_test_fns.inc" -+ -+# This test is run in environment with two DCs ('localdc' and 'localvampiredc') -+# The 'net ads join' has these two steps: -+# 1. create machine account at DC ('-S' points to 'localvampiredc') -+# 2. create keytab and sync the KVNO from a DC -+# -+# It must be ensured that in step #2 the keytab code contacts the same DC -+# ('localvampiredc'). The configuration below tries to break it. -+# We disable [SAF/DOMAIN/...] and [SAFJOIN/DOMAIN/...] by setting TTL to '-1' -+# And via setting 'password server' to 'localdc' we manage that -+# get_dc_list() returns 'localdc' instead of 'localvampiredc' -+# -+# As long as the keytab code is not explicitly told to use the same DC as join, -+# we get failure: -+# gensec_gse_client_prepare_ccache: Kinit for F0D26C71F6$@SAMBA.EXAMPLE.COM to access ldap/localdc.samba.example.com failed: Client not found in Kerberos database: NT_STATUS_LOGON_FAILURE -+ -+cat <>$BASEDIR/$WORKDIR/client.conf -+sync machine password to keytab = $BASEDIR/keytab:account_name:machine_password:sync_kvno -+password server = $DC_SERVER -+saf: join ttl = -1 -+saf: ttl = -1 -+EOF -+ -+testit "join" $VALGRIND $net_tool ads join -S$SERVER -U$DC_USERNAME%$DC_PASSWORD || failed=$(expr $failed + 1) -+ -+testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=$(expr $failed + 1) -+ -+rm -rf $BASEDIR/$WORKDIR -+ -+exit $failed --- -2.51.0 - - -From f05b9d0ff206bd0ab8ab7b98f7458775ff0274dd Mon Sep 17 00:00:00 2001 -From: Andreas Schneider -Date: Mon, 28 Jul 2025 10:43:36 +0200 -Subject: [PATCH 43/43] s3:net: Pass down the server from cmdline to - sync_pw2keytabs() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This makes sure that during 'net ads join' the keytab create code -- sync_pw2keytabs() talks to the same DC at what the machine account -was created. - -BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 - -Signed-off-by: Andreas Schneider -Signed-off-by: Pavel Filipenský -Pair-Programmed-With: Pavel Filipenský - -Reviewed-by: Alexander Bokovoy - -Autobuild-User(master): Pavel Filipensky -Autobuild-Date(master): Fri Sep 5 13:38:33 UTC 2025 on atb-devel-224 - -(backported from commit 5d1d3a8b568b5a07ed1ed537d20aa93820cecc14) ---- - selftest/knownfail | 1 - - source3/include/secrets.h | 25 ++++++++++++++---------- - source3/libads/ads_proto.h | 2 +- - source3/libads/kerberos_keytab.c | 24 ++++++++++++++++++++--- - source3/libads/trusts_util.c | 15 ++++++++------ - source3/libads/util.c | 10 ++++++---- - source3/libnet/libnet_join.c | 2 +- - source3/passdb/machine_account_secrets.c | 10 ++++++---- - source3/utils/net.c | 10 ++++++---- - source3/utils/net_ads.c | 2 +- - 10 files changed, 66 insertions(+), 35 deletions(-) - -diff --git a/selftest/knownfail b/selftest/knownfail -index 94d9ffc5fcb..a7a2e2b2251 100644 ---- a/selftest/knownfail -+++ b/selftest/knownfail -@@ -340,7 +340,6 @@ - ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.* - ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dbcheck_dangling_multi_valued_clean - ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing --^samba4.blackbox.net_ads_join.join - - # We currently don't send referrals for LDAP modify of non-replicated attrs - ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* -diff --git a/source3/include/secrets.h b/source3/include/secrets.h -index a454c8bb8ff..061b9c6ef34 100644 ---- a/source3/include/secrets.h -+++ b/source3/include/secrets.h -@@ -125,12 +125,15 @@ char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domai - NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain, - TALLOC_CTX *mem_ctx, - struct secrets_domain_info1 **pinfo); --NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, -- const char *cleartext_unix, -- TALLOC_CTX *mem_ctx, -- struct secrets_domain_info1 **pinfo, -- struct secrets_domain_info1_change **pprev, -- NTSTATUS (*sync_pw2keytabs_fn)(void)); -+NTSTATUS secrets_prepare_password_change( -+ const char *domain, -+ const char *dcname, -+ const char *cleartext_unix, -+ TALLOC_CTX *mem_ctx, -+ struct secrets_domain_info1 **pinfo, -+ struct secrets_domain_info1_change **pprev, -+ NTSTATUS (*sync_pw2keytabs_fn)(const char *), -+ const char *opt_host); - NTSTATUS secrets_failed_password_change(const char *change_server, - NTSTATUS local_status, - NTSTATUS remote_status, -@@ -139,10 +142,12 @@ NTSTATUS secrets_defer_password_change(const char *change_server, - NTSTATUS local_status, - NTSTATUS remote_status, - const struct secrets_domain_info1 *info); --NTSTATUS secrets_finish_password_change(const char *change_server, -- NTTIME change_time, -- const struct secrets_domain_info1 *info, -- NTSTATUS (*sync_pw2keytabs_fn)(void)); -+NTSTATUS secrets_finish_password_change( -+ const char *change_server, -+ NTTIME change_time, -+ const struct secrets_domain_info1 *info, -+ NTSTATUS (*sync_pw2keytabs_fn)(const char *), -+ const char *prefer_dc); - bool secrets_delete_machine_password_ex(const char *domain, const char *realm); - bool secrets_delete_domain_sid(const char *domain); - char *secrets_fetch_prev_machine_password(const char *domain); -diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h -index 8440c35e46d..2e67eef155c 100644 ---- a/source3/libads/ads_proto.h -+++ b/source3/libads/ads_proto.h -@@ -230,6 +230,6 @@ struct spn_struct { - /* parse a windows style SPN, returns NULL if parsing fails */ - struct spn_struct *parse_spn(TALLOC_CTX *ctx, const char *srvprinc); - --NTSTATUS sync_pw2keytabs(void); -+NTSTATUS sync_pw2keytabs(const char *prefer_dc); - - #endif /* _LIBADS_ADS_PROTO_H_ */ -diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c -index 5913db299ad..a549f42e5d3 100644 ---- a/source3/libads/kerberos_keytab.c -+++ b/source3/libads/kerberos_keytab.c -@@ -84,6 +84,7 @@ struct pw2kt_global_state { - char *ad_upn; - char *ad_sam_account; - char **ad_spn_array; -+ const char *prefer_dc; - size_t ad_num_spns; - /* This is from secrets.db */ - struct secrets_domain_info1 *info; -@@ -852,8 +853,11 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_global_state *state) - int count; - bool ok; - TALLOC_CTX *tmp_ctx = talloc_stackframe(); -- ADS_STRUCT *ads = ads_init( -- tmp_ctx, lp_realm(), lp_workgroup(), NULL, ADS_SASL_SIGN); -+ ADS_STRUCT *ads = ads_init(tmp_ctx, -+ lp_realm(), -+ lp_workgroup(), -+ state->prefer_dc, -+ ADS_SASL_SIGN); - - if (ads == NULL) { - DBG_ERR("ads_init() failed\n"); -@@ -1012,7 +1016,20 @@ static bool pw2kt_default_keytab_name(char *name_str, size_t name_size) - return true; - } - --NTSTATUS sync_pw2keytabs(void) -+/** -+ * @internal -+ * -+ * @brief Sync machine password from secrets to keytab -+ * -+ * @param prefer_dc The DC we should talk to. This is especially important -+ * during domain join. Pass NULL if we should pick a random -+ * one. -+ * -+ * @return An NTSTATUS error code. -+ * -+ * @see NT_STATUS_IS_OK() -+ */ -+NTSTATUS sync_pw2keytabs(const char *prefer_dc) - { - TALLOC_CTX *frame = talloc_stackframe(); - const struct loadparm_substitution *lp_sub = -@@ -1038,6 +1055,7 @@ NTSTATUS sync_pw2keytabs(void) - TALLOC_FREE(frame); - return NT_STATUS_NO_MEMORY; - } -+ state->prefer_dc = prefer_dc; - - lp_ptr = lp_sync_machine_password_to_keytab(); - if (lp_ptr == NULL) { -diff --git a/source3/libads/trusts_util.c b/source3/libads/trusts_util.c -index 6f805f2365e..e774a0b73e6 100644 ---- a/source3/libads/trusts_util.c -+++ b/source3/libads/trusts_util.c -@@ -325,10 +325,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, - &info, - &prev, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ NULL /* opt_host */); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", - domain)); -@@ -429,10 +430,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, - prev->password->change_time, - info, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ prev->password->change_server); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", - domain)); -@@ -578,10 +580,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, - info->next_change->change_time, - info, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ info->next_change->change_server); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("secrets_finish_password_change() failed for domain %s!\n", - domain)); -diff --git a/source3/libads/util.c b/source3/libads/util.c -index 243dd09f3d0..360e556ab9b 100644 ---- a/source3/libads/util.c -+++ b/source3/libads/util.c -@@ -59,10 +59,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip - &info, - &prev, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ ads->auth.kdc_server); - if (!NT_STATUS_IS_OK(status)) { - return ADS_ERROR_NT(status); - } -@@ -138,10 +139,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip - now, - info, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ ads->auth.kdc_server); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1,("Failed to save machine password\n")); - return ADS_ERROR_NT(status); -diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c -index f98d132d50f..a3a08e34295 100644 ---- a/source3/libnet/libnet_join.c -+++ b/source3/libnet/libnet_join.c -@@ -866,7 +866,7 @@ static ADS_STATUS libnet_join_set_etypes(TALLOC_CTX *mem_ctx, - static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx, - struct libnet_JoinCtx *r) - { -- NTSTATUS ntstatus = sync_pw2keytabs(); -+ NTSTATUS ntstatus = sync_pw2keytabs(r->in.dc_name); - - return NT_STATUS_IS_OK(ntstatus); - } -diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c -index 21571349004..8e16b2c5640 100644 ---- a/source3/passdb/machine_account_secrets.c -+++ b/source3/passdb/machine_account_secrets.c -@@ -1674,7 +1674,8 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, - TALLOC_CTX *mem_ctx, - struct secrets_domain_info1 **pinfo, - struct secrets_domain_info1_change **pprev, -- NTSTATUS (*sync_pw2keytabs_fn)(void)) -+ NTSTATUS (*sync_pw2keytabs_fn)(const char *), -+ const char *opt_host) - { - TALLOC_CTX *frame = talloc_stackframe(); - struct db_context *db = NULL; -@@ -1770,7 +1771,7 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, - } - - if (prev == NULL && sync_pw2keytabs_fn != NULL) { -- status = sync_pw2keytabs_fn(); -+ status = sync_pw2keytabs_fn(opt_host); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Sync of machine password failed.\n"); - dbwrap_transaction_cancel(db); -@@ -2023,7 +2024,8 @@ NTSTATUS secrets_defer_password_change(const char *change_server, - NTSTATUS secrets_finish_password_change(const char *change_server, - NTTIME change_time, - const struct secrets_domain_info1 *cookie, -- NTSTATUS (*sync_pw2keytabs_fn)(void)) -+ NTSTATUS (*sync_pw2keytabs_fn)(const char *), -+ const char *prefer_dc) - { - const char *domain = cookie->domain_info.name.string; - TALLOC_CTX *frame = talloc_stackframe(); -@@ -2102,7 +2104,7 @@ NTSTATUS secrets_finish_password_change(const char *change_server, - } - - if (sync_pw2keytabs_fn != NULL) { -- status = sync_pw2keytabs_fn(); -+ status = sync_pw2keytabs_fn(prefer_dc); - if (!NT_STATUS_IS_OK(status)) { - DBG_ERR("Sync of machine password failed.\n"); - TALLOC_FREE(frame); -diff --git a/source3/utils/net.c b/source3/utils/net.c -index 7ce93ced79e..ecabd980d0c 100644 ---- a/source3/utils/net.c -+++ b/source3/utils/net.c -@@ -235,10 +235,11 @@ static int net_changesecretpw(struct net_context *c, int argc, - &info, - &prev, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ c->opt_host); - if (!NT_STATUS_IS_OK(status)) { - d_fprintf(stderr, - _("Unable to write the machine account password in the secrets database")); -@@ -261,10 +262,11 @@ static int net_changesecretpw(struct net_context *c, int argc, - now, - info, - #ifdef HAVE_ADS -- sync_pw2keytabs); -+ sync_pw2keytabs, - #else -- NULL); -+ NULL, - #endif -+ c->opt_host); - if (!NT_STATUS_IS_OK(status)) { - d_fprintf(stderr, - _("Unable to write the machine account password in the secrets database")); -diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c -index 394a65d9a59..8fdf39f2e00 100644 ---- a/source3/utils/net_ads.c -+++ b/source3/utils/net_ads.c -@@ -2968,7 +2968,7 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a - goto out; - } - -- ntstatus = sync_pw2keytabs(); -+ ntstatus = sync_pw2keytabs(c->opt_host); - ret = NT_STATUS_IS_OK(ntstatus) ? 0 : 1; - out: - TALLOC_FREE(tmp_ctx); --- -2.51.0 - diff --git a/SOURCES/redhat-4.22.patch b/SOURCES/redhat-4.22.patch new file mode 100644 index 0000000..ae37fbd --- /dev/null +++ b/SOURCES/redhat-4.22.patch @@ -0,0 +1,492 @@ +From b0ff8644c06b01252bdbac6a31c77c5781d4b5a0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= +Date: Tue, 29 Jul 2025 11:19:07 +0200 +Subject: [PATCH 1/3] selftest: Add the short name for localvampiredc to hosts + file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 + +Signed-off-by: Pavel Filipenský +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 5d2f60ae5aa96751b74901ae5384291ef338b152) +--- + selftest/target/Samba4.pm | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm +index 9da339f6239..af0434a8e6b 100755 +--- a/selftest/target/Samba4.pm ++++ b/selftest/target/Samba4.pm +@@ -878,7 +878,7 @@ nogroup:x:65534:nobody + + my $hostname = lc($ctx->{hostname}); + open(HOSTS, ">>$ctx->{nsswrap_hosts}"); +- if ($hostname eq "localdc") { ++ if ($hostname eq "localdc" || $hostname eq "localvampiredc") { + print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; + print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n"; + } else { +-- +2.51.0 + + +From 03431792b4707e50afc8f9e356f08a91f4fb67c3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20Filipensk=C3=BD?= +Date: Mon, 4 Aug 2025 11:20:54 +0200 +Subject: [PATCH 2/3] tests: Add test for 'net ads join' to a preferred DC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 + +Signed-off-by: Pavel Filipenský +Reviewed-by: Alexander Bokovoy +(cherry picked from commit 36f6ac547c09f492d1dcab11570e8bcbd377cf26) +--- + selftest/knownfail | 1 + + source4/selftest/tests.py | 1 + + .../test_net_ads_join_to_preferred_dc.sh | 61 +++++++++++++++++++ + 3 files changed, 63 insertions(+) + create mode 100755 testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh + +diff --git a/selftest/knownfail b/selftest/knownfail +index ab2d79d7114..7c0e9dd00e7 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -335,6 +335,7 @@ + ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.* + ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dbcheck_dangling_multi_valued_clean + ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing ++^samba4.blackbox.net_ads_join.join + + # We currently don't send referrals for LDAP modify of non-replicated attrs + ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* +diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py +index 9c5e85e428a..14a41ba77ed 100755 +--- a/source4/selftest/tests.py ++++ b/source4/selftest/tests.py +@@ -902,6 +902,7 @@ plantestsuite("samba4.blackbox.rfc2307_mapping", + plantestsuite("samba4.blackbox.chgdcpass", "chgdcpass", [os.path.join(bbdir, "test_chgdcpass.sh"), '$SERVER', r"CHGDCPASS\$", '$REALM', '$DOMAIN', '$PREFIX/chgdcpass', "aes256-cts-hmac-sha1-96", '$PREFIX/chgdcpass', smbclient3]) + plantestsuite("samba4.blackbox.samba_upgradedns(chgdcpass:local)", "chgdcpass:local", [os.path.join(bbdir, "test_samba_upgradedns.sh"), '$SERVER', '$REALM', '$PREFIX', '$SELFTEST_PREFIX/chgdcpass']) + plantestsuite("samba4.blackbox.net_ads", "ad_dc:client", [os.path.join(bbdir, "test_net_ads.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) ++plantestsuite("samba4.blackbox.net_ads_join", "vampire_dc:client", [os.path.join(bbdir, "test_net_ads_join_to_preferred_dc.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX']) + plantestsuite("samba4.blackbox.net_offlinejoin", "ad_dc:client", [os.path.join(bbdir, "test_net_offline.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS']) + plantestsuite("samba4.blackbox.client_etypes_all(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'all', '17_18_23']) + plantestsuite("samba4.blackbox.client_etypes_legacy(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'legacy', '23']) +diff --git a/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh +new file mode 100755 +index 00000000000..1bebc2f4dbe +--- /dev/null ++++ b/testprogs/blackbox/test_net_ads_join_to_preferred_dc.sh +@@ -0,0 +1,61 @@ ++if [ $# -lt 4 ]; then ++ cat </dev/null | sha1sum | cut -b 1-10) ++ ++RUNDIR=$(pwd) ++cd $BASEDIR ++WORKDIR=$(mktemp -d -p .) ++WORKDIR=$(basename $WORKDIR) ++cp -a client/* $WORKDIR/ ++sed -ri "s@(dir|directory) = (.*)/client/@\1 = \2/$WORKDIR/@" $WORKDIR/client.conf ++sed -ri "s/netbios name = .*/netbios name = $HOSTNAME/" $WORKDIR/client.conf ++rm -f $WORKDIR/private/secrets.tdb ++cd $RUNDIR ++ ++failed=0 ++ ++net_tool="$BINDIR/net --configfile=$BASEDIR/$WORKDIR/client.conf --option=security=ads" ++ ++# Load test functions ++. $(dirname $0)/subunit.sh ++. "$(dirname "${0}")/common_test_fns.inc" ++ ++# This test is run in environment with two DCs ('localdc' and 'localvampiredc') ++# The 'net ads join' has these two steps: ++# 1. create machine account at DC ('-S' points to 'localvampiredc') ++# 2. create keytab and sync the KVNO from a DC ++# ++# It must be ensured that in step #2 the keytab code contacts the same DC ++# ('localvampiredc'). The configuration below tries to break it. ++# We disable [SAF/DOMAIN/...] and [SAFJOIN/DOMAIN/...] by setting TTL to '-1' ++# And via setting 'password server' to 'localdc' we manage that ++# get_dc_list() returns 'localdc' instead of 'localvampiredc' ++# ++# As long as the keytab code is not explicitly told to use the same DC as join, ++# we get failure: ++# gensec_gse_client_prepare_ccache: Kinit for F0D26C71F6$@SAMBA.EXAMPLE.COM to access ldap/localdc.samba.example.com failed: Client not found in Kerberos database: NT_STATUS_LOGON_FAILURE ++ ++cat <>$BASEDIR/$WORKDIR/client.conf ++sync machine password to keytab = $BASEDIR/keytab:account_name:machine_password:sync_kvno ++password server = $DC_SERVER ++saf: join ttl = -1 ++saf: ttl = -1 ++EOF ++ ++testit "join" $VALGRIND $net_tool ads join -S$SERVER -U$DC_USERNAME%$DC_PASSWORD || failed=$(expr $failed + 1) ++ ++testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=$(expr $failed + 1) ++ ++rm -rf $BASEDIR/$WORKDIR ++ ++exit $failed +-- +2.51.0 + + +From 5cff37091161976a979752351003c9c1deb0d39f Mon Sep 17 00:00:00 2001 +From: Andreas Schneider +Date: Mon, 28 Jul 2025 10:43:36 +0200 +Subject: [PATCH 3/3] s3:net: Pass down the server from cmdline to + sync_pw2keytabs() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This makes sure that during 'net ads join' the keytab create code +- sync_pw2keytabs() talks to the same DC at what the machine account +was created. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15905 + +Signed-off-by: Andreas Schneider +Signed-off-by: Pavel Filipenský +Pair-Programmed-With: Pavel Filipenský + +Reviewed-by: Alexander Bokovoy + +Autobuild-User(master): Pavel Filipensky +Autobuild-Date(master): Fri Sep 5 13:38:33 UTC 2025 on atb-devel-224 + +(cherry picked from commit 5d1d3a8b568b5a07ed1ed537d20aa93820cecc14) +--- + selftest/knownfail | 1 - + source3/include/secrets.h | 25 ++++++++++++++---------- + source3/libads/ads_proto.h | 2 +- + source3/libads/kerberos_keytab.c | 24 ++++++++++++++++++++--- + source3/libads/trusts_util.c | 15 ++++++++------ + source3/libads/util.c | 10 ++++++---- + source3/libnet/libnet_join.c | 2 +- + source3/passdb/machine_account_secrets.c | 10 ++++++---- + source3/utils/net.c | 10 ++++++---- + source3/utils/net_ads.c | 2 +- + 10 files changed, 66 insertions(+), 35 deletions(-) + +diff --git a/selftest/knownfail b/selftest/knownfail +index 7c0e9dd00e7..ab2d79d7114 100644 +--- a/selftest/knownfail ++++ b/selftest/knownfail +@@ -335,7 +335,6 @@ + ^samba.tests.dcerpc.dnsserver.samba.tests.dcerpc.dnsserver.DnsserverTests.test_security_descriptor.* + ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dbcheck_dangling_multi_valued_clean + ^samba4.blackbox.dbcheck-links.release-4-5-0-pre1.dangling_multi_valued_check_missing +-^samba4.blackbox.net_ads_join.join + + # We currently don't send referrals for LDAP modify of non-replicated attrs + ^samba4.ldap.rodc.python\(rodc\).__main__.RodcTests.test_modify_nonreplicated.* +diff --git a/source3/include/secrets.h b/source3/include/secrets.h +index a454c8bb8ff..061b9c6ef34 100644 +--- a/source3/include/secrets.h ++++ b/source3/include/secrets.h +@@ -125,12 +125,15 @@ char *secrets_domain_info_string(TALLOC_CTX *mem_ctx, const struct secrets_domai + NTSTATUS secrets_fetch_or_upgrade_domain_info(const char *domain, + TALLOC_CTX *mem_ctx, + struct secrets_domain_info1 **pinfo); +-NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, +- const char *cleartext_unix, +- TALLOC_CTX *mem_ctx, +- struct secrets_domain_info1 **pinfo, +- struct secrets_domain_info1_change **pprev, +- NTSTATUS (*sync_pw2keytabs_fn)(void)); ++NTSTATUS secrets_prepare_password_change( ++ const char *domain, ++ const char *dcname, ++ const char *cleartext_unix, ++ TALLOC_CTX *mem_ctx, ++ struct secrets_domain_info1 **pinfo, ++ struct secrets_domain_info1_change **pprev, ++ NTSTATUS (*sync_pw2keytabs_fn)(const char *), ++ const char *opt_host); + NTSTATUS secrets_failed_password_change(const char *change_server, + NTSTATUS local_status, + NTSTATUS remote_status, +@@ -139,10 +142,12 @@ NTSTATUS secrets_defer_password_change(const char *change_server, + NTSTATUS local_status, + NTSTATUS remote_status, + const struct secrets_domain_info1 *info); +-NTSTATUS secrets_finish_password_change(const char *change_server, +- NTTIME change_time, +- const struct secrets_domain_info1 *info, +- NTSTATUS (*sync_pw2keytabs_fn)(void)); ++NTSTATUS secrets_finish_password_change( ++ const char *change_server, ++ NTTIME change_time, ++ const struct secrets_domain_info1 *info, ++ NTSTATUS (*sync_pw2keytabs_fn)(const char *), ++ const char *prefer_dc); + bool secrets_delete_machine_password_ex(const char *domain, const char *realm); + bool secrets_delete_domain_sid(const char *domain); + char *secrets_fetch_prev_machine_password(const char *domain); +diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h +index 8440c35e46d..2e67eef155c 100644 +--- a/source3/libads/ads_proto.h ++++ b/source3/libads/ads_proto.h +@@ -230,6 +230,6 @@ struct spn_struct { + /* parse a windows style SPN, returns NULL if parsing fails */ + struct spn_struct *parse_spn(TALLOC_CTX *ctx, const char *srvprinc); + +-NTSTATUS sync_pw2keytabs(void); ++NTSTATUS sync_pw2keytabs(const char *prefer_dc); + + #endif /* _LIBADS_ADS_PROTO_H_ */ +diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c +index 49a892e5a55..1d4f9c12e1d 100644 +--- a/source3/libads/kerberos_keytab.c ++++ b/source3/libads/kerberos_keytab.c +@@ -84,6 +84,7 @@ struct pw2kt_global_state { + char *ad_upn; + char *ad_sam_account; + char **ad_spn_array; ++ const char *prefer_dc; + size_t ad_num_spns; + /* This is from secrets.db */ + struct secrets_domain_info1 *info; +@@ -869,8 +870,11 @@ static ADS_STATUS pw2kt_get_dc_info(struct pw2kt_global_state *state) + int count; + bool ok; + TALLOC_CTX *tmp_ctx = talloc_stackframe(); +- ADS_STRUCT *ads = ads_init( +- tmp_ctx, lp_realm(), lp_workgroup(), NULL, ADS_SASL_SIGN); ++ ADS_STRUCT *ads = ads_init(tmp_ctx, ++ lp_realm(), ++ lp_workgroup(), ++ state->prefer_dc, ++ ADS_SASL_SIGN); + + if (ads == NULL) { + DBG_ERR("ads_init() failed\n"); +@@ -1029,7 +1033,20 @@ static bool pw2kt_default_keytab_name(char *name_str, size_t name_size) + return true; + } + +-NTSTATUS sync_pw2keytabs(void) ++/** ++ * @internal ++ * ++ * @brief Sync machine password from secrets to keytab ++ * ++ * @param prefer_dc The DC we should talk to. This is especially important ++ * during domain join. Pass NULL if we should pick a random ++ * one. ++ * ++ * @return An NTSTATUS error code. ++ * ++ * @see NT_STATUS_IS_OK() ++ */ ++NTSTATUS sync_pw2keytabs(const char *prefer_dc) + { + TALLOC_CTX *frame = talloc_stackframe(); + const struct loadparm_substitution *lp_sub = +@@ -1055,6 +1072,7 @@ NTSTATUS sync_pw2keytabs(void) + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } ++ state->prefer_dc = prefer_dc; + + lp_ptr = lp_sync_machine_password_to_keytab(); + if (lp_ptr == NULL) { +diff --git a/source3/libads/trusts_util.c b/source3/libads/trusts_util.c +index 6a39f32f350..c51c556e86b 100644 +--- a/source3/libads/trusts_util.c ++++ b/source3/libads/trusts_util.c +@@ -360,10 +360,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, + &info, + &prev, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ NULL /* opt_host */); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", + domain)); +@@ -610,10 +611,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, + prev->password->change_time, + info, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ prev->password->change_server); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n", + domain)); +@@ -759,10 +761,11 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, + info->next_change->change_time, + info, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ info->next_change->change_server); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("secrets_finish_password_change() failed for domain %s!\n", + domain)); +diff --git a/source3/libads/util.c b/source3/libads/util.c +index 243dd09f3d0..360e556ab9b 100644 +--- a/source3/libads/util.c ++++ b/source3/libads/util.c +@@ -59,10 +59,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip + &info, + &prev, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ ads->auth.kdc_server); + if (!NT_STATUS_IS_OK(status)) { + return ADS_ERROR_NT(status); + } +@@ -138,10 +139,11 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip + now, + info, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ ads->auth.kdc_server); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("Failed to save machine password\n")); + return ADS_ERROR_NT(status); +diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c +index 5796c68e2e0..cb997dcbe23 100644 +--- a/source3/libnet/libnet_join.c ++++ b/source3/libnet/libnet_join.c +@@ -867,7 +867,7 @@ static ADS_STATUS libnet_join_set_etypes(TALLOC_CTX *mem_ctx, + static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx, + struct libnet_JoinCtx *r) + { +- NTSTATUS ntstatus = sync_pw2keytabs(); ++ NTSTATUS ntstatus = sync_pw2keytabs(r->in.dc_name); + + return NT_STATUS_IS_OK(ntstatus); + } +diff --git a/source3/passdb/machine_account_secrets.c b/source3/passdb/machine_account_secrets.c +index 0679535f026..568d77a3892 100644 +--- a/source3/passdb/machine_account_secrets.c ++++ b/source3/passdb/machine_account_secrets.c +@@ -1674,7 +1674,8 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, + TALLOC_CTX *mem_ctx, + struct secrets_domain_info1 **pinfo, + struct secrets_domain_info1_change **pprev, +- NTSTATUS (*sync_pw2keytabs_fn)(void)) ++ NTSTATUS (*sync_pw2keytabs_fn)(const char *), ++ const char *opt_host) + { + TALLOC_CTX *frame = talloc_stackframe(); + struct db_context *db = NULL; +@@ -1770,7 +1771,7 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname, + } + + if (prev == NULL && sync_pw2keytabs_fn != NULL) { +- status = sync_pw2keytabs_fn(); ++ status = sync_pw2keytabs_fn(opt_host); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Sync of machine password failed.\n"); + dbwrap_transaction_cancel(db); +@@ -2023,7 +2024,8 @@ NTSTATUS secrets_defer_password_change(const char *change_server, + NTSTATUS secrets_finish_password_change(const char *change_server, + NTTIME change_time, + const struct secrets_domain_info1 *cookie, +- NTSTATUS (*sync_pw2keytabs_fn)(void)) ++ NTSTATUS (*sync_pw2keytabs_fn)(const char *), ++ const char *prefer_dc) + { + const char *domain = cookie->domain_info.name.string; + TALLOC_CTX *frame = talloc_stackframe(); +@@ -2102,7 +2104,7 @@ NTSTATUS secrets_finish_password_change(const char *change_server, + } + + if (sync_pw2keytabs_fn != NULL) { +- status = sync_pw2keytabs_fn(); ++ status = sync_pw2keytabs_fn(prefer_dc); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Sync of machine password failed.\n"); + TALLOC_FREE(frame); +diff --git a/source3/utils/net.c b/source3/utils/net.c +index 7ce93ced79e..ecabd980d0c 100644 +--- a/source3/utils/net.c ++++ b/source3/utils/net.c +@@ -235,10 +235,11 @@ static int net_changesecretpw(struct net_context *c, int argc, + &info, + &prev, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ c->opt_host); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, + _("Unable to write the machine account password in the secrets database")); +@@ -261,10 +262,11 @@ static int net_changesecretpw(struct net_context *c, int argc, + now, + info, + #ifdef HAVE_ADS +- sync_pw2keytabs); ++ sync_pw2keytabs, + #else +- NULL); ++ NULL, + #endif ++ c->opt_host); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, + _("Unable to write the machine account password in the secrets database")); +diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c +index 46531210411..753b957e43f 100644 +--- a/source3/utils/net_ads.c ++++ b/source3/utils/net_ads.c +@@ -2965,7 +2965,7 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a + net_use_krb_machine_account(c); + } + +- ntstatus = sync_pw2keytabs(); ++ ntstatus = sync_pw2keytabs(c->opt_host); + ret = NT_STATUS_IS_OK(ntstatus) ? 0 : 1; + return ret; + } +-- +2.51.0 + diff --git a/SOURCES/samba-4.21.3.tar.asc b/SOURCES/samba-4.21.3.tar.asc deleted file mode 100644 index a9ae09f..0000000 --- a/SOURCES/samba-4.21.3.tar.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAmd796YACgkQqplEL7aA -tiAdpA/9EodazpG4Vo534WW3aKiBxEWt0LzGjDZ6GUbTpCRIJE+a/a36rxbAgHFH -Mpc9mVnCI6/UWv1plnsLwNG4RnC/o0tDrw2ttvIX/ZEiWEPWU38sgfZ+vlwX1r2B -3Hi7Uym4br0SmPwrep5kPfjnE396ftlnC6YMHXZ+tg3i6y8m6msr8rEB8ejLx7RF -qXtJ/YO4HK2DrE51l/Ziyav9FwBgVoE9Sl0oXwLoUX5lhWh6qNe8Qz+bd0s36x1e -5w+ocSNuD2ph5uO1W+pmdOJyMgq8QFchOwxdHi454nRrelp7Kwtb2ARBHrFwoQ+V -kinQlufJ0sb59imso65Tl3EGuuV61CUQgGx9Ln9/wBMXdiPDNhi/H+ikH2AeVzpz -DFuL9WEU/HYT4thCKlNox5T8s90/95vT5MlN2q/CJhFjIti6mb7iM9uxatGFzUBI -A3OxPRc9IbORTEPYxLzsuPrxo+bcFXg0Go8SoNa4W3NYIehMDqnuWOOnC/ixleta -ig635ivxl5owC1CC/GzilBnJ/Tq4bzbZOrYDeYCYa5FkXv9EaTIT9JQcRr0LJcDS -Z43RoD9g9tG6tIea0XyAaPkfVillfnf70vcuelxycl3bhhuvSZUQ+8cqQ0vuUg1V -pcclEjCcgIecIR9r2zSv5S5EldS7hQ6t5pCC5KcJKyeq+LLaj5s= -=DkSu ------END PGP SIGNATURE----- diff --git a/SOURCES/samba-4.22.4.tar.asc b/SOURCES/samba-4.22.4.tar.asc new file mode 100644 index 0000000..ba5e216 --- /dev/null +++ b/SOURCES/samba-4.22.4.tar.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEgfXigyvSVFoYl7cTqplEL7aAtiAFAminOhEACgkQqplEL7aA +tiDtRg//e/Jocf1iPjaEtiR2tGQSnqQPdaaRId8luFu0ykevvIiR+GL2IctJnvWZ +IYL/svmWAlLULgb+13S1Gs7CGYTievrh+OaEnuo+CmnGpNYUFO/yyymBW9eWFGA4 +bA6ilMjE2KgyCakvBT22mL9IFGZQsKQh46YXjs4hCKZdadx733/Znwj/kIkm0Wxl +S6gnxstroM5zUbA/Xw26KUOBTd0mTZXXKH14HSH1XX3RNgA0/FsZ+kde4Y+VUwP+ +t/LvuNqN2s/pyUeKd8eoiZv7zTwUT1gsvoBTWP8kzmubtBbxz4abJ9QCEb/HEdkv +iMh1RbRQZRKpmIo/NzAMRhxDyuVtzg69Egn19iLjnPfmrpqDZpxhi5csNumIFKsi +bFmT7/KTZfKvsg9h5SfHL3JeblYbEQNjIhDutdZ3yJ+JymAkaWjChHqY0wTwiZbX +pHing+t+c4SRx2064/jBFn48kdj1JweEaGSGdEEwa7zejMHLcl7vKheyGqSTWMYH +XiBtm1kN2gLrgazLFNXKTD9YectYPmRkiv6f1hUhqLfac2jkwIdWeT1LIPqJ2fMw +YrNk4UYYS4L7PZSXUJ3r88RGPWJvTa7WQrM556uxcspCr7W6TauMRe0hKquqOekH +0J4jD+hmfuEQ/LryC29rSLSNG0N99v2nWuAn78KxUk7FuZ9H4og= +=D+9R +-----END PGP SIGNATURE----- diff --git a/SOURCES/samba.logrotate b/SOURCES/samba.logrotate index 40f85aa..43bef68 100644 --- a/SOURCES/samba.logrotate +++ b/SOURCES/samba.logrotate @@ -1,4 +1,4 @@ -/var/log/samba/log.* { +/var/log/samba/*log* { compress dateext maxage 365 diff --git a/SPECS/samba.spec b/SPECS/samba.spec index dd29b7d..3fdcf3c 100644 --- a/SPECS/samba.spec +++ b/SPECS/samba.spec @@ -2,7 +2,7 @@ ## (rpmautospec version 0.6.5) ## RPMAUTOSPEC: autorelease, autochangelog %define autorelease(e:s:pb:n) %{?-p:0.}%{lua: - release_number = 14; + release_number = 6; base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); print(release_number + base_release_number - 1); }%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} @@ -16,7 +16,7 @@ # or # rpmbuild --rebuild --with testsuite samba.src.rpm # -%bcond_with testsuite +%bcond testsuite 0 # Build with internal talloc, tevent, tdb # @@ -24,132 +24,97 @@ # or # rpmbuild --rebuild --with=testsuite --with=includelibs samba.src.rpm # -%bcond_with includelibs +%bcond includelibs 0 # fedpkg mockbuild --with=ccache -%bcond_with ccache +%bcond ccache 0 # ctdb is enabled by default, you can disable it with: --without clustering -%bcond_without clustering +%bcond clustering 1 # Define _make_verbose if it doesn't exist (RHEL8) %{!?_make_verbose:%define _make_verbose V=1 VERBOSE=1} # Build with Active Directory Domain Controller support by default on Fedora %if 0%{?fedora} -%bcond_without dc +%bcond dc 1 %else -%bcond_with dc +%bcond dc 0 %endif # Build a libsmbclient package by default -%bcond_without libsmbclient +%bcond libsmbclient 1 # Build a libwbclient package by default -%bcond_without libwbclient +%bcond libwbclient 1 # Build with winexe by default %if 0%{?rhel} %ifarch x86_64 -%bcond_without winexe +%bcond winexe 1 %else -%bcond_with winexe +%bcond winexe 0 #endifarch %endif %else -%bcond_without winexe +%bcond winexe 1 %endif # Build vfs_ceph module and ctdb cepth mutex helper by default on 64bit Fedora %if 0%{?fedora} %ifarch aarch64 ppc64le s390x x86_64 riscv64 -%bcond_without vfs_cephfs -%bcond_without ceph_mutex +%bcond vfs_cephfs 1 +%bcond ceph_mutex 1 %else -%bcond_with vfs_cephfs -%bcond_with ceph_mutex +%bcond vfs_cephfs 0 +%bcond ceph_mutex 0 #endifarch %endif %else -%bcond_with vfs_cephfs -%bcond_with ceph_mutex +%bcond vfs_cephfs 0 +%bcond ceph_mutex 0 #endif fedora %endif -# Build vfs_gluster module by default on 64bit Fedora -%global is_rhgs 0 -%if "%{dist}" == ".el7rhgs" || "%{dist}" == ".el8rhgs" -%global is_rhgs 1 -%endif - %if 0%{?fedora} %ifarch aarch64 ppc64le s390x x86_64 riscv64 -%bcond_without vfs_glusterfs +%bcond vfs_glusterfs 1 %else -%bcond_with vfs_glusterfs +%bcond vfs_glusterfs 0 #endifarch %endif -#else rhel -%else - -%if 0%{?is_rhgs} -# Enable on rhgs x86_64 -%ifarch x86_64 -%bcond_without vfs_glusterfs -%else -%bcond_with vfs_glusterfs -#endifarch -%endif -%else -%bcond_with vfs_glusterfs -#endif is_rhgs -%endif - #endif fedora %endif # Build vfs_io_uring module by default on 64bit Fedora -%if 0%{?fedora} || 0%{?rhel} >= 8 - %ifarch aarch64 ppc64le s390x x86_64 riscv64 -%bcond_without vfs_io_uring +%bcond vfs_io_uring 1 %else -%bcond_with vfs_io_uring +%bcond vfs_io_uring 0 #endifarch %endif -%else -%bcond_with vfs_io_uring -#endif fedora || rhel >= 8 -%endif - # Build the ctdb-pcp-pmda package by default on Fedora, except for i686 where # pcp is no longer supported %if 0%{?fedora} %ifnarch i686 -%bcond_without pcp_pmda +%bcond pcp_pmda 1 %endif %else -%bcond_with pcp_pmda +%bcond pcp_pmda 0 %endif # Build the etcd helpers by default on Fedora %if 0%{?fedora} -%bcond_without etcd_mutex +%bcond etcd_mutex 1 %else -%bcond_with etcd_mutex -%endif - -%if 0%{?fedora} || 0%{?rhel} >= 9 -%bcond_without gpupdate -%else -%bcond_with gpupdate +%bcond etcd_mutex 0 %endif %ifarch aarch64 ppc64le s390x x86_64 @@ -158,7 +123,7 @@ %bcond lmdb 0 %endif -%global samba_version 4.21.3 +%global samba_version 4.22.4 # The release field is extended: # [.][.]%%{?dist}[.] @@ -186,7 +151,7 @@ %global libdcerpc_so_version 0 %global libndr_krb5pac_so_version 0 %global libndr_nbt_so_version 0 -%global libndr_so_version 5 +%global libndr_so_version 6 %global libndr_standard_so_version 0 %global libnetapi_so_version 1 %global libsamba_credentials_so_version 1 @@ -203,9 +168,9 @@ %global libsmbclient_so_version 0 %global libwbclient_so_version 0 -%global talloc_version 2.4.2 -%global tdb_version 1.4.12 -%global tevent_version 0.16.1 +%global talloc_version 2.4.3 +%global tdb_version 1.4.13 +%global tevent_version 0.16.2 %global required_mit_krb5 1.20.1 @@ -264,11 +229,11 @@ Source202: samba.abignore # # git clone git@gitlab.com:samba-redhat/samba.git # cd samba -# git checkout v4-21-redhat -# git format-patch --stdout -l1 --no-renames -N > redhat-4.21.patch +# git checkout v4-22-redhat +# git format-patch --stdout -l1 --no-renames -N > redhat-4.22.patch # where N is number of commits -Patch0: redhat-4.21.patch +Patch0: redhat-4.22.patch Requires(pre): %{name}-common = %{samba_depver} Requires: %{name}-common = %{samba_depver} @@ -304,7 +269,7 @@ Obsoletes: samba-swat < %{samba_depver} Provides: samba4-swat = %{samba_depver} Obsoletes: samba4-swat < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} BuildRequires: make BuildRequires: gcc @@ -332,6 +297,7 @@ BuildRequires: libicu-devel BuildRequires: libcmocka-devel BuildRequires: libtirpc-devel BuildRequires: libuuid-devel +BuildRequires: libxcrypt-devel BuildRequires: libxslt %if %{with lmdb} BuildRequires: lmdb @@ -369,7 +335,7 @@ BuildRequires: zlib-devel >= 1.2.3 BuildRequires: pkgconfig(libsystemd) -%ifnarch i686 riscv64 +%ifnarch i686 %if 0%{?fedora} >= 37 BuildRequires: mold %endif @@ -398,9 +364,7 @@ BuildRequires: librados-devel BuildRequires: python3-etcd %endif -%if %{with gpupdate} BuildRequires: cepces-certmonger >= 0.3.8 -%endif # pidl requirements BuildRequires: perl(ExtUtils::MakeMaker) @@ -497,7 +461,7 @@ Obsoletes: samba4-client < %{samba_depver} Requires(post): %{_sbindir}/update-alternatives Requires(postun): %{_sbindir}/update-alternatives -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description client The %{name}-client package provides some SMB/CIFS clients to complement @@ -550,7 +514,7 @@ Requires: libldb = %{samba_depver} Requires: libwbclient = %{samba_depver} %endif -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %if %{without dc} && %{without testsuite} Obsoletes: samba-dc < %{samba_depver} @@ -592,7 +556,7 @@ Requires: libnetapi = %{samba_depver} Requires: libwbclient = %{samba_depver} %endif -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description common-tools The samba-common-tools package contains tools for SMB/CIFS clients. @@ -662,7 +626,7 @@ Requires: bind-utils Provides: samba4-dc = %{samba_depver} Obsoletes: samba4-dc < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description dc The samba-dc package provides AD Domain Controller functionality @@ -690,7 +654,7 @@ Requires: libwbclient = %{samba_depver} Provides: samba4-dc-libs = %{samba_depver} Obsoletes: samba4-dc-libs < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description dc-libs The %{name}-dc-libs package contains the libraries needed by the DC to @@ -709,7 +673,7 @@ Requires: bind Requires: libldb = %{samba_depver} Requires: libwbclient = %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description dc-bind-dlz The %{name}-dc-bind-dlz package contains the libraries for bind to manage all @@ -745,7 +709,7 @@ Requires: %{name}-libs = %{samba_depver} Requires: libldb = %{samba_depver} Requires: libwbclient = %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description vfs-cephfs Samba VFS module for Ceph distributed storage system integration. @@ -762,7 +726,7 @@ Requires: %{name}-client-libs = %{samba_depver} Requires: libldb = %{samba_depver} Requires: libwbclient = %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description vfs-iouring Samba VFS module for io_uring instance integration. @@ -787,14 +751,13 @@ Requires: libwbclient = %{samba_depver} Obsoletes: samba-glusterfs < %{samba_depver} Provides: samba-glusterfs = %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description vfs-glusterfs Samba VFS module for GlusterFS integration. %endif ### GPUPDATE -%if %{with gpupdate} %package gpupdate Summary: Samba GPO support for clients Requires: cepces-certmonger @@ -803,14 +766,12 @@ Requires: %{name}-ldb-ldap-modules = %{samba_depver} Requires: python3-%{name} = %{samba_depver} # samba-tool needs python3-samba-dc also on non-dc build Requires: python3-%{name}-dc = %{samba_depver} +BuildArch: noarch %description gpupdate This package provides the samba-gpupdate tool to apply Group Policy Objects (GPO) on Samba clients. -#endif with gpupdate -%endif - ### KRB5-PRINTING %package krb5-printing Summary: Samba CUPS backend for printing with Kerberos @@ -851,7 +812,7 @@ Requires: libwbclient = %{samba_depver} Provides: samba4-libs = %{samba_depver} Obsoletes: samba4-libs < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description libs The %{name}-libs package contains the libraries needed by programs that link @@ -952,7 +913,7 @@ Requires: libsmbclient = %{samba_depver} Requires: libwbclient = %{samba_depver} %endif -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description -n python3-%{name} The python3-%{name} package contains the Python 3 libraries needed by programs @@ -1026,7 +987,7 @@ Requires: perl(Archive::Tar) Provides: samba4-test = %{samba_depver} Obsoletes: samba4-test < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description test %{name}-test provides testing tools for both the server and client @@ -1046,7 +1007,7 @@ Requires: libwbclient = %{samba_depver} Provides: %{name}-test-devel = %{samba_depver} Obsoletes: %{name}-test-devel < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description test-libs %{name}-test-libs provides libraries required by the testing tools. @@ -1056,6 +1017,7 @@ Provides: bundled(libreplace) Summary: Provides support for non-root user shares Requires: %{name} = %{samba_depver} Requires: %{name}-common-tools = %{samba_depver} +BuildArch: noarch %description usershares Installing this package will provide a configuration file, group and @@ -1090,7 +1052,7 @@ Obsoletes: samba4-winbind < %{samba_depver} # Old NetworkManager expects the dispatcher scripts in a different place Conflicts: NetworkManager < 1.20 -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description winbind The samba-winbind package provides the winbind NSS library, and some client @@ -1113,7 +1075,7 @@ Requires: libwbclient = %{samba_depver} Provides: samba4-winbind-clients = %{samba_depver} Obsoletes: samba4-winbind-clients < %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description winbind-clients The samba-winbind-clients package provides the wbinfo and ntlm_auth @@ -1143,7 +1105,7 @@ Requires(post): %{_sbindir}/update-alternatives Requires(postun): %{_sbindir}/update-alternatives Requires(preun): %{_sbindir}/update-alternatives -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description winbind-krb5-locator The winbind krb5 locator is a plugin for the system kerberos library to allow @@ -1159,7 +1121,7 @@ Requires: libwbclient = %{samba_depver} %endif Requires: pam -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description winbind-modules The samba-winbind-modules package provides the NSS library and a PAM module @@ -1175,7 +1137,7 @@ Requires: %{name}-common-libs = %{samba_depver} Requires: libldb = %{samba_depver} Requires: libwbclient = %{samba_depver} -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description winexe Winexe is a Remote Windows-command executor @@ -1211,7 +1173,7 @@ Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units -Provides: bundled(libreplace) +Provides: bundled(libreplace) = %{samba_depver} %description -n ctdb CTDB is a cluster implementation of the TDB database used by Samba and other @@ -1239,6 +1201,7 @@ Performance Co-Pilot (PCP) support for CTDB Summary: CTDB ETCD mutex helper Requires: ctdb = %{samba_depver} Requires: python3-etcd +BuildArch: noarch %description -n ctdb-etcd-mutex Support for using an existing ETCD cluster as a mutex helper for CTDB @@ -1265,11 +1228,14 @@ Support for using an existing CEPH cluster as a mutex helper for CTDB %package -n libldb Summary: A schema-less, ldap like, API and database License: LGPL-3.0-or-later +%if %{without includelibs} Requires: libtalloc%{?_isa} >= %{talloc_version} Requires: libtdb%{?_isa} >= %{tdb_version} Requires: libtevent%{?_isa} >= %{tevent_version} +Requires: samba-common-libs = %{samba_depver} +# /endif without includelibs +%endif -Provides: bundled(libreplace) Obsoletes: libldb < 0:2.10 Provides: libldb = 0:2.10 Provides: libldb = %{samba_depver} @@ -1283,9 +1249,12 @@ servers, or use local tdb databases. Summary: Developer tools for the LDB library License: LGPL-3.0-or-later Requires: libldb%{?_isa} = %{samba_depver} +%if %{without includelibs} Requires: libtdb-devel%{?_isa} >= %{tdb_version} Requires: libtalloc-devel%{?_isa} >= %{talloc_version} Requires: libtevent-devel%{?_isa} >= %{tevent_version} +# /endif without includelibs +%endif Obsoletes: libldb-devel < 0:2.10 Provides: libldb-devel = 0:2.10 @@ -1310,7 +1279,10 @@ Tools to manage LDB files Summary: Python bindings for the LDB library License: LGPL-3.0-or-later Requires: libldb%{?_isa} = %{samba_depver} +%if %{without includelibs} Requires: python3-tdb%{?_isa} >= %{tdb_version} +# /endif without includelibs +%endif Requires: samba-client-libs = %{samba_depver} %{?python_provide:%python_provide python3-ldb} @@ -1487,6 +1459,7 @@ install -d -m 0755 %{buildroot}/var/lib/samba/sysvol install -d -m 0755 %{buildroot}/var/lib/samba/usershares install -d -m 0755 %{buildroot}/var/lib/samba/winbindd_privileged install -d -m 0755 %{buildroot}/var/log/samba/old +install -d -m 0755 %{buildroot}/run/ctdb install -d -m 0755 %{buildroot}/run/samba install -d -m 0755 %{buildroot}/run/winbindd install -d -m 0755 %{buildroot}/%{_libdir}/samba @@ -1561,11 +1534,6 @@ for i in \ done %endif -%if %{without gpupdate} -rm -f %{buildroot}%{_sbindir}/samba-gpupdate -rm -f %{buildroot}%{_mandir}/man8/samba-gpupdate.8* -%endif - %if %{without vfs_glusterfs} rm -f %{buildroot}%{_mandir}/man8/vfs_glusterfs.8* %endif @@ -1702,12 +1670,12 @@ fi %post krb5-printing %{_sbindir}/update-alternatives --install %{_libexecdir}/samba/cups_backend_smb \ - cups_backend_smb \ - %{_libexecdir}/samba/smbspool_krb5_wrapper 50 + cups_backend_smb \ + %{_libexecdir}/samba/smbspool_krb5_wrapper 50 %postun krb5-printing if [ $1 -eq 0 ] ; then - %{_sbindir}/update-alternatives --remove cups_backend_smb %{_libexecdir}/samba/smbspool_krb5_wrapper + %{_sbindir}/update-alternatives --remove cups_backend_smb %{_libexecdir}/samba/smbspool_krb5_wrapper fi %ldconfig_scriptlets libs @@ -2049,7 +2017,6 @@ fi %{_libdir}/samba/libposix-eadb-private-samba.so %{_libdir}/samba/libprinter-driver-private-samba.so %{_libdir}/samba/libprinting-migrate-private-samba.so -%{_libdir}/samba/libreplace-private-samba.so %{_libdir}/samba/libregistry-private-samba.so %{_libdir}/samba/libsamba-cluster-support-private-samba.so %{_libdir}/samba/libsamba-debug-private-samba.so @@ -2132,6 +2099,7 @@ fi %files common-libs # common libraries %{_libdir}/samba/libcmdline-private-samba.so +%{_libdir}/samba/libreplace-private-samba.so %dir %{_libdir}/samba/ldb @@ -2463,12 +2431,9 @@ fi %endif ### GPUPDATE -%if %{with gpupdate} %files gpupdate %{_mandir}/man8/samba-gpupdate.8* %{_sbindir}/samba-gpupdate -#endif with gpupdate -%endif ### KRB5-PRINTING %files krb5-printing @@ -2681,8 +2646,11 @@ fi %{python3_sitearch}/samba/dnsresolver.py %dir %{python3_sitearch}/samba/domain %{python3_sitearch}/samba/domain/__init__.py +%dir %{python3_sitearch}/samba/domain/__pycache__ %{python3_sitearch}/samba/domain/__pycache__/__init__.*.pyc +%dir %{python3_sitearch}/samba/domain/models %{python3_sitearch}/samba/domain/models/__init__.py +%dir %{python3_sitearch}/samba/domain/models/__pycache__ %{python3_sitearch}/samba/domain/models/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/domain/models/__pycache__/auth_policy.*.pyc %{python3_sitearch}/samba/domain/models/__pycache__/auth_silo.*.pyc @@ -2891,28 +2859,28 @@ fi %dir %{python3_sitearch}/samba/netcmd/domain/auth/__pycache__ %{python3_sitearch}/samba/netcmd/domain/auth/__pycache__/__init__.*.pyc %dir %{python3_sitearch}/samba/netcmd/domain/auth/policy -%{python3_sitearch}/samba/netcmd/domain/auth/policy/computer_allowed_to_authenticate_to.py %{python3_sitearch}/samba/netcmd/domain/auth/policy/__init__.py -%{python3_sitearch}/samba/netcmd/domain/auth/policy/policy.py %dir %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__ -%{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/computer_allowed_to_authenticate_to.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/__init__.*.pyc +%{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/computer_allowed_to_authenticate_to.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/policy.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/service_allowed_to_authenticate_from.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/service_allowed_to_authenticate_to.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/user_allowed_to_authenticate_from.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/policy/__pycache__/user_allowed_to_authenticate_to.*.pyc +%{python3_sitearch}/samba/netcmd/domain/auth/policy/computer_allowed_to_authenticate_to.py +%{python3_sitearch}/samba/netcmd/domain/auth/policy/policy.py %{python3_sitearch}/samba/netcmd/domain/auth/policy/service_allowed_to_authenticate_from.py %{python3_sitearch}/samba/netcmd/domain/auth/policy/service_allowed_to_authenticate_to.py %{python3_sitearch}/samba/netcmd/domain/auth/policy/user_allowed_to_authenticate_from.py %{python3_sitearch}/samba/netcmd/domain/auth/policy/user_allowed_to_authenticate_to.py %dir %{python3_sitearch}/samba/netcmd/domain/auth/silo %{python3_sitearch}/samba/netcmd/domain/auth/silo/__init__.py -%{python3_sitearch}/samba/netcmd/domain/auth/silo/member.py %dir %{python3_sitearch}/samba/netcmd/domain/auth/silo/__pycache__ %{python3_sitearch}/samba/netcmd/domain/auth/silo/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/silo/__pycache__/member.*.pyc %{python3_sitearch}/samba/netcmd/domain/auth/silo/__pycache__/silo.*.pyc +%{python3_sitearch}/samba/netcmd/domain/auth/silo/member.py %{python3_sitearch}/samba/netcmd/domain/auth/silo/silo.py %{python3_sitearch}/samba/netcmd/domain/backup.py %dir %{python3_sitearch}/samba/netcmd/domain/claim @@ -2965,6 +2933,7 @@ fi %{python3_sitearch}/samba/netcmd/schema.py %dir %{python3_sitearch}/samba/netcmd/service_account %{python3_sitearch}/samba/netcmd/service_account/__init__.py +%dir %{python3_sitearch}/samba/netcmd/service_account/__pycache__ %{python3_sitearch}/samba/netcmd/service_account/__pycache__/__init__.*.pyc %{python3_sitearch}/samba/netcmd/service_account/__pycache__/group_msa_membership.*.pyc %{python3_sitearch}/samba/netcmd/service_account/__pycache__/service_account.*.pyc @@ -3077,6 +3046,7 @@ fi %if %{with includelibs} %{_libdir}/samba/libpyldb-util.cpython*.so +%{_libdir}/samba/libpytalloc-util.cpython*.so %{python3_sitearch}/__pycache__/_ldb_text*.pyc %{python3_sitearch}/__pycache__/_tdb_text*.pyc @@ -3085,8 +3055,7 @@ fi %{python3_sitearch}/_tdb_text.py %{python3_sitearch}/_tevent.cpython*.so %{python3_sitearch}/ldb.cpython*.so -#FIXME why is it missing? -#%{python3_sitearch}/talloc.cpython*.so +%{python3_sitearch}/talloc.cpython*.so %{python3_sitearch}/tdb.cpython*.so %{python3_sitearch}/tevent.py #endif with includelibs @@ -3253,6 +3222,7 @@ fi %{python3_sitearch}/samba/tests/__pycache__/py_credentials.*.pyc %{python3_sitearch}/samba/tests/__pycache__/registry.*.pyc %{python3_sitearch}/samba/tests/__pycache__/reparsepoints.*.pyc +%{python3_sitearch}/samba/tests/__pycache__/rust.*.pyc %{python3_sitearch}/samba/tests/__pycache__/s3idmapdb.*.pyc %{python3_sitearch}/samba/tests/__pycache__/s3param.*.pyc %{python3_sitearch}/samba/tests/__pycache__/s3passdb.*.pyc @@ -3486,6 +3456,7 @@ fi %{python3_sitearch}/samba/tests/krb5/__pycache__/kpasswd_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/lockout_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/ms_kile_client_principal_lookup_tests.*.pyc +%{python3_sitearch}/samba/tests/krb5/__pycache__/netlogon.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/nt_hash_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/pac_align_tests.*.pyc %{python3_sitearch}/samba/tests/krb5/__pycache__/pkinit_tests.*.pyc @@ -3528,6 +3499,7 @@ fi %{python3_sitearch}/samba/tests/krb5/kpasswd_tests.py %{python3_sitearch}/samba/tests/krb5/lockout_tests.py %{python3_sitearch}/samba/tests/krb5/ms_kile_client_principal_lookup_tests.py +%{python3_sitearch}/samba/tests/krb5/netlogon.py %{python3_sitearch}/samba/tests/krb5/nt_hash_tests.py %{python3_sitearch}/samba/tests/krb5/pac_align_tests.py %{python3_sitearch}/samba/tests/krb5/pkinit_tests.py @@ -3563,9 +3535,11 @@ fi %dir %{python3_sitearch}/samba/tests/ndr %{python3_sitearch}/samba/tests/ndr/gkdi.py %{python3_sitearch}/samba/tests/ndr/gmsa.py +%{python3_sitearch}/samba/tests/ndr/sd.py %dir %{python3_sitearch}/samba/tests/ndr/__pycache__ %{python3_sitearch}/samba/tests/ndr/__pycache__/gkdi.*.pyc %{python3_sitearch}/samba/tests/ndr/__pycache__/gmsa.*.pyc +%{python3_sitearch}/samba/tests/ndr/__pycache__/sd.*.pyc %{python3_sitearch}/samba/tests/ndr/__pycache__/wbint.*.pyc %{python3_sitearch}/samba/tests/ndr/wbint.py %{python3_sitearch}/samba/tests/netbios.py @@ -3600,6 +3574,7 @@ fi %{python3_sitearch}/samba/tests/py_credentials.py %{python3_sitearch}/samba/tests/registry.py %{python3_sitearch}/samba/tests/reparsepoints.py +%{python3_sitearch}/samba/tests/rust.py %{python3_sitearch}/samba/tests/s3idmapdb.py %{python3_sitearch}/samba/tests/s3param.py %{python3_sitearch}/samba/tests/s3passdb.py @@ -3816,6 +3791,7 @@ fi %config(noreplace) %{_sysconfdir}/ctdb/ctdb.conf %config(noreplace) %{_sysconfdir}/ctdb/notify.sh %config(noreplace) %{_sysconfdir}/ctdb/debug-hung-script.sh +%config(noreplace) %{_sysconfdir}/ctdb/ctdb-backup-persistent-tdbs.sh %config(noreplace) %{_sysconfdir}/ctdb/ctdb-crash-cleanup.sh %config(noreplace) %{_sysconfdir}/ctdb/debug_locks.sh @@ -3859,8 +3835,8 @@ fi %{_libexecdir}/ctdb/ctdb_natgw %{_libexecdir}/ctdb/ctdb-path %{_libexecdir}/ctdb/ctdb_recovery_helper +%{_libexecdir}/ctdb/ctdb_smnotify_helper %{_libexecdir}/ctdb/ctdb_takeover_helper -%{_libexecdir}/ctdb/smnotify %{_libexecdir}/ctdb/statd_callout %{_libexecdir}/ctdb/statd_callout_helper %{_libexecdir}/ctdb/tdb_mutex_check @@ -3883,6 +3859,8 @@ fi %{_mandir}/man7/ctdb-tunables.7.gz %{_mandir}/man7/ctdb-statistics.7.gz +%ghost %dir /run/ctdb + %{_tmpfilesdir}/ctdb.conf %{_unitdir}/ctdb.service @@ -3909,6 +3887,7 @@ fi %{_datadir}/ctdb/events/legacy/60.nfs.script %{_datadir}/ctdb/events/legacy/70.iscsi.script %{_datadir}/ctdb/events/legacy/91.lvs.script +%{_datadir}/ctdb/events/legacy/95.database.script %dir %{_datadir}/ctdb/scripts %{_datadir}/ctdb/scripts/winbind_ctdb_updatekeytab.sh @@ -3950,6 +3929,7 @@ fi %endif %files -n libldb +%license lib/ldb/LICENSE %{_libdir}/libldb.so.* %dir %{_libdir}/samba %{_libdir}/samba/libldb-key-value-private-samba.so @@ -4009,41 +3989,50 @@ fi %changelog ## START: Generated by rpmautospec -* Wed Sep 10 2025 Pavel Filipenský - 0:4.21.3-14 -- resolves: RHEL-113388 - Rebuild for zstream +* Thu Sep 11 2025 Pavel Filipenský - 0:4.22.4-6 +- resolves: RHEL-104147 - Fix 'net ads join' in setups with multiple DCs -* Sat Sep 06 2025 Pavel Filipenský - 0:4.21.3-13 -- resolves: RHEL-113388 - Fix 'net ads join' in setups with multiple DCs +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.4-5 +- resolves: RHEL-101761 - Fix DC discovery after Windows netlogon hardening + (follow-up, main fix is in samba-4.22.2-4.el9) -* Wed Aug 27 2025 Pavel Filipenský - 0:4.21.3-12 -- resolves: RHEL-101766 - Fix DC discovery after Windows netlogon hardening - (follow-up, main fix is in samba-4.21.3-7) - -* Wed Aug 27 2025 Pavel Filipenský - 0:4.21.3-11 -- resolves: RHEL-111311 - Fix winbind fork bomb in 'IPA with AD trust' +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.4-4 +- resolves: RHEL-110530 - Fix winbind fork bomb in 'IPA with AD trust' environment -* Wed Aug 27 2025 Pavel Filipenský - 0:4.21.3-10 -- resolves: RHEL-102934 - Fix samba-gpupdate to process empty GPO Link +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.4-3 +- resolves: RHEL-102932 - Fix samba-gpupdate to process empty GPO Link -* Wed Aug 27 2025 Pavel Filipenský - 0:4.21.3-9 -- resolves: RHEL-105624 - Fix 'net ads kerberos kinit' +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.4-2 +- resolves: RHEL-105623 - Fix 'net ads kerberos kinit' -* Wed Aug 27 2025 Pavel Filipenský - 0:4.21.3-8 -- resolves: RHEL-103411 - smb.conf: Remove the '@' for NIX groups, we - removed NIS support +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.4-1 +- Update to version 4.22.4 +- resolves: RHEL-89873 -* Mon Jul 07 2025 Andreas Schneider - 0:4.21.3-7 -- Fix DC discovery after Windows netlogon hardening +* Thu Aug 21 2025 Pavel Filipenský - 0:4.22.3-3 +- resolves: RHEL-103410 - Update '@printadmin' in sbm.conf -* Tue Jun 17 2025 Pavel Filipenský - 0:4.21.3-6 -- resolves: RHEL-97486 +* Tue Jul 08 2025 Pavel Filipenský - 0:4.22.3-2 +- resolves: RHEL-102370 - Fix issue with unresponsive second DC when using + idmap_ad -* Wed Apr 16 2025 Pavel Filipenský - 0:4.21.3-5 -- resolves: RHEL-75587 - Fix deadlock between two smbd processes +* Tue Jul 08 2025 Pavel Filipenský - 0:4.22.3-1 +- Update to version 4.22.3 +- resolves: RHEL-89873 -* Mon Mar 31 2025 Pavel Filipenský - 0:4.21.3-4 -- resolves: RHEL-85348 - Fix winbindd memory leak +* Mon Jul 07 2025 Andreas Schneider - 0:4.22.2-4 +- Fix DC discovery after Windows netlogon hardening. + +* Tue Jun 10 2025 Pavel Filipenský - 0:4.22.2-3 +- resolves: RHEL-87571 - Fix deadlock between two smbd processes + +* Tue Jun 10 2025 Pavel Filipenský - 0:4.22.2-2 +- resolves: RHEL-85342 - Fix winbindd memory leak + +* Tue Jun 10 2025 Pavel Filipenský - 0:4.22.2-1 +- Update to version 4.22.2 +- resolves: RHEL-89873 * Mon Feb 17 2025 Pavel Filipenský - 0:4.21.3-3 - resolves: RHEL-78773 - Fix keytab generation