From 18699d003b1d4460ffb36db61860e6c31acbf1cb Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 26 Nov 2007 11:44:30 +0100 Subject: Prevent winbindd from segfaulting due to corrupted cache tdb. If we try to flush the caches and due to a corrupted tdb we and have no tdb context close the tdb and validate it. Initialize the cache afterwards again. (This used to be commit d0c0f91fb9f3438a18c6f47ed894f525beb75cbf) --- source3/winbindd/winbindd.c | 18 +++++++++++++++++- source3/winbindd/winbindd_cache.c | 22 +++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'source3') diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index 07cf22618e..dfad50bf96 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -121,7 +121,23 @@ static void flush_caches(void) otherwise cached access denied errors due to restrict anonymous hang around until the sequence number changes. */ - wcache_invalidate_cache(); + if (wcache_invalidate_cache() < 0) { + DEBUG(0, ("invalidating the cache failed; revalidate the cache\n")); + /* Close the cache to be able to valdite the cache */ + close_winbindd_cache(); + /* + * Ensure all cache and idmap caches are consistent + * before we initialize the cache again. + */ + if (winbindd_validate_cache() < 0) { + DEBUG(0, ("corrupted tdb found, trying to restore backup\n")); + } + + /* Initialize cache again. */ + if (!initialize_winbindd_cache()) { + exit(1); + } + } } /* Handle the signal by unlinking socket and exiting */ diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index f63c7a5b2f..62a68aa8aa 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -2261,7 +2261,7 @@ void wcache_invalidate_samlogon(struct winbindd_domain *domain, netsamlogon_clear_cached_user(cache->tdb, info3); } -void wcache_invalidate_cache(void) +int wcache_invalidate_cache(void) { struct winbindd_domain *domain; @@ -2270,9 +2270,15 @@ void wcache_invalidate_cache(void) DEBUG(10, ("wcache_invalidate_cache: invalidating cache " "entries for %s\n", domain->name)); - if (cache) - tdb_traverse(cache->tdb, traverse_fn, NULL); + if (cache) { + if (cache->tdb) { + tdb_traverse(cache->tdb, traverse_fn, NULL); + } else { + return -1; + } + } } + return 0; } bool init_wcache(void) @@ -2354,6 +2360,16 @@ bool initialize_winbindd_cache(void) return True; } +void close_winbindd_cache() +{ + if (!wcache) + return; + if (wcache->tdb) { + tdb_close(wcache->tdb); + wcache->tdb = NULL; + } +} + void cache_store_response(pid_t pid, struct winbindd_response *response) { fstring key_str; -- cgit