The branch, master has been updated
via d6ee9b04f2c s3-winbindd: make sure we always have
WINBINDD_CACHE_VERSION in winbindd_cache.tdb
via 7136a6ba39d s3-winbindd: provide one wcache_open() function for all
tdb opens
via 6667f255076 s3-winbindd: make initialize_winbindd_cache() static
via ffe1883d7d6 s3-winbind: make wcache_store_seqnum static
via c4606bc4063 s3-winbindd: Fix winbind NDR caching.
via 073a9482f0a s3-selftest: add tests for winbindd_cache.tdb sanity
from 209cac897ba selftest: use common and simpler code to read config.h
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit d6ee9b04f2c9875953fba60a26a764ef61670114
Author: Günther Deschner <[email protected]>
Date: Fri Jul 25 22:50:08 2025 +0200
s3-winbindd: make sure we always have WINBINDD_CACHE_VERSION in
winbindd_cache.tdb
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
Autobuild-User(master): Andreas Schneider <[email protected]>
Autobuild-Date(master): Mon Dec 8 09:59:58 UTC 2025 on atb-devel-224
commit 7136a6ba39ddf025e85c639f3e53f53f8ff46cb5
Author: Günther Deschner <[email protected]>
Date: Fri Jul 25 23:05:39 2025 +0200
s3-winbindd: provide one wcache_open() function for all tdb opens
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
commit 6667f25507687c19f3d3eaa3301a7ccd2433d4e3
Author: Günther Deschner <[email protected]>
Date: Fri Jul 25 22:43:55 2025 +0200
s3-winbindd: make initialize_winbindd_cache() static
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
commit ffe1883d7d68dd933b6fa41e3af722e8688ff882
Author: Günther Deschner <[email protected]>
Date: Fri Aug 1 16:10:48 2025 +0200
s3-winbind: make wcache_store_seqnum static
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
commit c4606bc40632869ff4f1036cf6899df400d15a53
Author: Günther Deschner <[email protected]>
Date: Thu Jul 17 16:49:03 2025 +0200
s3-winbindd: Fix winbind NDR caching.
All of winbindd's core caching relies on NDR entries. Those entries can
not be stored in winbindd_cache.tdb via wcache_store_ndr() as long as
there is no SEQNUM entry present in the cache.
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
commit 073a9482f0ace8847781181a552e0d0ceb897d0c
Author: Günther Deschner <[email protected]>
Date: Fri Jul 25 17:58:59 2025 +0200
s3-selftest: add tests for winbindd_cache.tdb sanity
Guenther
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15963
Signed-off-by: Guenther Deschner <[email protected]>
Reviewed-by: Andreas Schneider <[email protected]>
-----------------------------------------------------------------------
Summary of changes:
source3/script/tests/test_winbind_cache_sanity.sh | 112 ++++++++++++++++++++++
source3/selftest/tests.py | 4 +
source3/winbindd/winbindd_cache.c | 82 ++++++++--------
source3/winbindd/winbindd_proto.h | 3 -
4 files changed, 160 insertions(+), 41 deletions(-)
create mode 100755 source3/script/tests/test_winbind_cache_sanity.sh
Changeset truncated at 500 lines:
diff --git a/source3/script/tests/test_winbind_cache_sanity.sh
b/source3/script/tests/test_winbind_cache_sanity.sh
new file mode 100755
index 00000000000..65d4e4cb778
--- /dev/null
+++ b/source3/script/tests/test_winbind_cache_sanity.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]; then
+ cat <<EOF
+Usage: test_winbind_cache_sanity.sh DOMAIN CACHE
+EOF
+ exit 1
+fi
+
+DOMAIN="$1"
+CACHE="$2"
+shift 2
+ADDARGS="$*"
+
+TDBTOOL=tdbtool
+if test -x "$BINDIR"/tdbtool; then
+ TDBTOOL=$BINDIR/tdbtool
+fi
+DBWRAP_TOOL=$BINDIR/dbwrap_tool
+WBINFO=$BINDIR/wbinfo
+
+incdir=$(dirname "$0")/../../../testprogs/blackbox
+. "$incdir"/subunit.sh
+
+
+#################################################
+## Test "$CACHE" presence
+#################################################
+
+testit "$CACHE presence" \
+ test -r "$CACHE" \
+ || failed=$((failed + 1))
+
+
+#################################################
+## Test very simple wbinfo query to fill up cache with NDR/ and SEQNUM/ entries
+#################################################
+
+separator=$("$WBINFO" --separator)
+
+testit "calling wbinfo -n$DOMAIN$separator to fillup cache" \
+ "$VALGRIND" "$WBINFO" -n "$DOMAIN$separator" \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+
+#################################################
+## Test "WINBINDD_CACHE_VERSION" presence
+#################################################
+
+KEY="WINBINDD_CACHE_VERSION"
+WINBINDD_CACHE_VER2=2
+
+testit "$KEY presence via dbwrap" \
+ "$VALGRIND" "$DBWRAP_TOOL" --persistent "$CACHE" fetch $KEY uint32 \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+#tdbtool will never fail so we have to parse the output...
+testit_grep "$KEY presence via tdbtool" "data 4 bytes" \
+ "$VALGRIND" "$TDBTOOL" "$CACHE" show "$KEY\\00" \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+current_ver=$("$DBWRAP_TOOL" --persistent "$CACHE" fetch $KEY uint32)
+
+testit "$KEY value via dbwrap to be WINBINDD_CACHE_VER2" \
+ test "$current_ver" = $WINBINDD_CACHE_VER2 \
+ || failed=$((failed + 1))
+
+
+#################################################
+## Test "SEQNUM/$DOMAIN" presence
+#################################################
+
+KEY="SEQNUM/$DOMAIN"
+
+testit "$KEY SEQNUM presence via dbwrap" \
+ "$VALGRIND" "$DBWRAP_TOOL" --persistent "$CACHE" exists "$KEY" \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+#tdbtool will never fail so we have to parse the output...
+testit_grep "$KEY SEQNUM presence via tdbtool" "data 8 bytes" \
+ "$VALGRIND" "$TDBTOOL" "$CACHE" show "$KEY\\00" \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+
+#################################################
+## Test
"NDR/$DOMAIN/3/\09\00\00\00\00\00\00\00\09\00\00\00$DOMAIN\00\00\00\00\01\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00"
presence
+## this is the resulting cache entry for a simple
+## wbinfo -n $DOMAIN\ query
+#################################################
+
+opnum=$($PYTHON -c'from samba.dcerpc.winbind import wbint_LookupName;
print(wbint_LookupName.opnum())')
+KEY="NDR/$DOMAIN/$opnum/\\09\\00\\00\\00\\00\\00\\00\\00\\09\\00\\00\\00$DOMAIN\\00\\00\\00\\00\\01\\00\\00\\00\\00\\00\\00\\00\\01\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00\\00"
+
+#DBWRAP_TOOL does not support non-null terminated keys so it cannot find it...
+#testit "$KEY NDR presence via dbwrap" \
+# "$VALGRIND" "$DBWRAP_TOOL" --persistent $CACHE exists $KEY \
+# "$ADDARGS" \
+# || failed=$((failed + 1))
+
+#tdbtool will never fail so we have to parse the output...
+# key 59 bytes
+testit_grep "$KEY NDR presence via tdbtool" "data 44 bytes" \
+ "$VALGRIND" "$TDBTOOL" "$CACHE" show "$KEY" \
+ "$ADDARGS" \
+ || failed=$((failed + 1))
+
+testok "$0" "$failed"
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 02046bcf1cb..7cad85fc4cb 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -718,6 +718,10 @@ plantestsuite("samba3.winbind_call_depth_trace", env,
[os.path.join(srcdir(),
"source3/script/tests/test_winbind_call_depth_trace.sh"),
smbcontrol, configuration, '$PREFIX', env])
+plantestsuite("samba3.winbind_cache_sanity", env,
+ [os.path.join(srcdir(),
+
"source3/script/tests/test_winbind_cache_sanity.sh"),
+ '$DOMAIN', '$LOCK_DIR/winbindd_cache.tdb'])
env = "fl2008r2dc:local"
plantestsuite("samba3.wbinfo_user_info", env,
diff --git a/source3/winbindd/winbindd_cache.c
b/source3/winbindd/winbindd_cache.c
index eb79586a2ca..3d908e4db08 100644
--- a/source3/winbindd/winbindd_cache.c
+++ b/source3/winbindd/winbindd_cache.c
@@ -505,8 +505,8 @@ static NTSTATUS fetch_cache_seqnum( struct winbindd_domain
*domain, time_t now )
return NT_STATUS_OK;
}
-bool wcache_store_seqnum(const char *domain_name, uint32_t seqnum,
- time_t last_seq_check)
+static bool wcache_store_seqnum(const char *domain_name, uint32_t seqnum,
+ time_t last_seq_check)
{
size_t len = strlen(domain_name);
char keystr[len+8];
@@ -3167,10 +3167,40 @@ bool wcache_invalidate_cache_noinit(void)
return true;
}
-static bool init_wcache(void)
+static TDB_CONTEXT *wcache_open(void)
{
char *db_path;
+ TDB_CONTEXT *tdb = NULL;
+ bool wcache_wiped = !lp_winbind_offline_logon();
+ db_path = wcache_path();
+ if (db_path == NULL) {
+ return NULL;
+ }
+
+ /* when working offline we must not clear the cache on restart */
+ tdb = tdb_open_log(db_path,
+ WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
+ TDB_INCOMPATIBLE_HASH |
+ (lp_winbind_offline_logon()
+ ? TDB_DEFAULT
+ : (TDB_DEFAULT |
+ TDB_CLEAR_IF_FIRST)),
+ O_RDWR | O_CREAT,
+ 0600);
+ TALLOC_FREE(db_path);
+
+ if (wcache_wiped) {
+ tdb_store_uint32(tdb,
+ WINBINDD_CACHE_VERSION_KEYSTR,
+ WINBINDD_CACHE_VERSION);
+ }
+
+ return tdb;
+}
+
+static bool init_wcache(void)
+{
if (wcache == NULL) {
wcache = SMB_XMALLOC_P(struct winbind_cache);
ZERO_STRUCTP(wcache);
@@ -3179,23 +3209,19 @@ static bool init_wcache(void)
if (wcache->tdb != NULL)
return true;
- db_path = wcache_path();
- if (db_path == NULL) {
- return false;
- }
-
- /* when working offline we must not clear the cache on restart */
- wcache->tdb = tdb_open_log(db_path,
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- TDB_INCOMPATIBLE_HASH |
- (lp_winbind_offline_logon() ?
TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
- O_RDWR|O_CREAT, 0600);
- TALLOC_FREE(db_path);
+ wcache->tdb = wcache_open();
if (wcache->tdb == NULL) {
DBG_ERR("Failed to open winbindd_cache.tdb!\n");
return false;
}
+ /*
+ * Create a dummy SEQNUM entry early, otherwise every call via the
+ * winbind NDR interface will fail to call wcache_store_ndr() when there
+ * is no SEQNUM present already
+ */
+ wcache_store_seqnum(lp_workgroup(), 0, 0);
+
return true;
}
@@ -3205,7 +3231,7 @@ static bool init_wcache(void)
only opener.
************************************************************************/
-bool initialize_winbindd_cache(void)
+static bool initialize_winbindd_cache(void)
{
bool cache_bad = false;
uint32_t vers = 0;
@@ -3390,8 +3416,6 @@ static int traverse_fn_cleanup(TDB_CONTEXT *the_tdb,
TDB_DATA kbuf,
/* flush the cache */
static void wcache_flush_cache(void)
{
- char *db_path;
-
if (!wcache)
return;
if (wcache->tdb) {
@@ -3402,18 +3426,7 @@ static void wcache_flush_cache(void)
return;
}
- db_path = wcache_path();
- if (db_path == NULL) {
- return;
- }
-
- /* when working offline we must not clear the cache on restart */
- wcache->tdb = tdb_open_log(db_path,
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- TDB_INCOMPATIBLE_HASH |
- (lp_winbind_offline_logon() ? TDB_DEFAULT :
(TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
- O_RDWR|O_CREAT, 0600);
- TALLOC_FREE(db_path);
+ wcache->tdb = wcache_open();
if (!wcache->tdb) {
DBG_ERR("Failed to open winbindd_cache.tdb!\n");
return;
@@ -4237,14 +4250,7 @@ int winbindd_validate_cache(void)
goto done;
}
- tdb = tdb_open_log(tdb_path,
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- TDB_INCOMPATIBLE_HASH |
- ( lp_winbind_offline_logon()
- ? TDB_DEFAULT
- : TDB_DEFAULT | TDB_CLEAR_IF_FIRST ),
- O_RDWR|O_CREAT,
- 0600);
+ tdb = wcache_open();
if (!tdb) {
DBG_ERR("winbindd_validate_cache: "
"error opening/initializing tdb\n");
diff --git a/source3/winbindd/winbindd_proto.h
b/source3/winbindd/winbindd_proto.h
index ae41923b244..1b6a4f5d115 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -143,7 +143,6 @@ void wcache_invalidate_samlogon(struct winbindd_domain
*domain,
const struct dom_sid *user_sid);
bool wcache_invalidate_cache(void);
bool wcache_invalidate_cache_noinit(void);
-bool initialize_winbindd_cache(void);
void close_winbindd_cache(void);
bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
char **domain_name, char **name,
@@ -178,8 +177,6 @@ bool wcache_tdc_fetch_list( struct winbindd_tdc_domain
**domains, size_t *num_do
bool wcache_tdc_add_domain( struct winbindd_domain *domain );
struct winbindd_tdc_domain * wcache_tdc_fetch_domain( TALLOC_CTX *ctx, const
char *name );
void wcache_tdc_clear( void );
-bool wcache_store_seqnum(const char *domain_name, uint32_t seqnum,
- time_t last_seq_check);
bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
uint32_t opnum, const DATA_BLOB *req, DATA_BLOB *resp);
void wcache_store_ndr(struct winbindd_domain *domain, uint32_t opnum,
--
Samba Shared Repository