From 2f5c2f4c72735c0764d6e022b770d8e8b9865c01 Mon Sep 17 00:00:00 2001
From: Bo Yang <boyang@samba.org>
Date: Tue, 9 Feb 2010 16:35:40 +0800
Subject: [PATCH] s3: Don't invalidate cache for uninitialized domains.

Signed-off-by: Bo Yang <boyang@samba.org>
(cherry picked from commit 9fed9011ffcd76c5a5dbf16f7d5e657b94f9fa50)
---
 source3/winbindd/winbindd.c       |   25 ++++++++++++++++++++++++-
 source3/winbindd/winbindd_cache.c |   27 +++++++++++++++++++++++++++
 source3/winbindd/winbindd_proto.h |    1 +
 3 files changed, 52 insertions(+), 1 deletions(-)

Index: source3/winbindd/winbindd.c
===================================================================
--- source3/winbindd/winbindd.c.orig
+++ source3/winbindd/winbindd.c
@@ -138,6 +138,29 @@ static void flush_caches(void)
 	}
 }
 
+static void flush_caches_noinit(void)
+{
+	/*
+	 * We need to invalidate cached user list entries on a SIGHUP
+         * otherwise cached access denied errors due to restrict anonymous
+         * hang around until the sequence number changes.
+	 * NB
+	 * Skip uninitialized domains when flush cache.
+	 * If domain is not initialized, it means it is never
+	 * used or never become online. look, wcache_invalidate_cache()
+	 * -> get_cache() -> init_dc_connection(). It causes a lot of traffic
+	 * for unused domains and large traffic for primay domain's DC if there
+	 * are many domains..
+	 */
+
+	if (!wcache_invalidate_cache_noinit()) {
+		DEBUG(0, ("invalidating the cache failed; revalidate the cache\n"));
+		if (!winbindd_cache_validate_and_initialize()) {
+			exit(1);
+		}
+	}
+}
+
 /* Handle the signal by unlinking socket and exiting */
 
 static void terminate(bool is_parent)
@@ -249,7 +272,7 @@ static void winbindd_sig_hup_handler(str
 	const char *file = (const char *)private_data;
 
 	DEBUG(1,("Reloading services after SIGHUP\n"));
-	flush_caches();
+	flush_caches_noinit();
 	reload_services_file(file);
 }
 
Index: source3/winbindd/winbindd_cache.c
===================================================================
--- source3/winbindd/winbindd_cache.c.orig
+++ source3/winbindd/winbindd_cache.c
@@ -2526,6 +2526,33 @@ bool wcache_invalidate_cache(void)
 	return true;
 }
 
+bool wcache_invalidate_cache_noinit(void)
+{
+	struct winbindd_domain *domain;
+
+	for (domain = domain_list(); domain; domain = domain->next) {
+		struct winbind_cache *cache;
+
+		/* Skip uninitialized domains. */
+		if (!domain->initialized && !domain->internal) {
+			continue;
+		}
+
+		cache = get_cache(domain);
+
+		DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
+			   "entries for %s\n", domain->name));
+		if (cache) {
+			if (cache->tdb) {
+				tdb_traverse(cache->tdb, traverse_fn, NULL);
+			} else {
+				return false;
+			}
+		}
+	}
+	return true;
+}
+
 bool init_wcache(void)
 {
 	if (wcache == NULL) {
Index: source3/winbindd/winbindd_proto.h
===================================================================
--- source3/winbindd/winbindd_proto.h.orig
+++ source3/winbindd/winbindd_proto.h
@@ -170,6 +170,7 @@ NTSTATUS wcache_save_creds(struct winbin
 void wcache_invalidate_samlogon(struct winbindd_domain *domain, 
 				struct netr_SamInfo3 *info3);
 bool wcache_invalidate_cache(void);
+bool wcache_invalidate_cache_noinit(void);
 bool init_wcache(void);
 bool initialize_winbindd_cache(void);
 void close_winbindd_cache(void);
