svn commit: samba r12340 - in trunk/source/nsswitch: .

gd at samba.org gd at samba.org
Mon Dec 19 02:50:16 GMT 2005


Author: gd
Date: 2005-12-19 02:50:15 +0000 (Mon, 19 Dec 2005)
New Revision: 12340

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12340

Log:
Basics to add offline capability to winbindd.

First, we must not clear the winbind_cache.tdb on each restart, then
remember if a domain was available in the "online" flag, try to detect
whether a domain has become online again each 30 seconds.

Also cache the trusted domains call for the offline case.

This approach will most probably be replaced with something better later
on.

Guenther

Modified:
   trunk/source/nsswitch/winbindd.h
   trunk/source/nsswitch/winbindd_cache.c
   trunk/source/nsswitch/winbindd_cm.c
   trunk/source/nsswitch/winbindd_util.c


Changeset:
Modified: trunk/source/nsswitch/winbindd.h
===================================================================
--- trunk/source/nsswitch/winbindd.h	2005-12-19 02:44:26 UTC (rev 12339)
+++ trunk/source/nsswitch/winbindd.h	2005-12-19 02:50:15 UTC (rev 12340)
@@ -158,6 +158,7 @@
 	BOOL active_directory;                 /* is this a win2k active directory ? */
 	BOOL primary;                          /* is this our primary domain ? */
 	BOOL internal;                         /* BUILTIN and member SAM */
+	BOOL online;			       /* is this domain available ? */
 
 	/* Lookup methods for this domain (LDAP or RPC) */
 	struct winbindd_methods *methods;

Modified: trunk/source/nsswitch/winbindd_cache.c
===================================================================
--- trunk/source/nsswitch/winbindd_cache.c	2005-12-19 02:44:26 UTC (rev 12339)
+++ trunk/source/nsswitch/winbindd_cache.c	2005-12-19 02:50:15 UTC (rev 12340)
@@ -58,12 +58,14 @@
 	if (opt_nocache)
 		return;
 
+	/* when working offline we must not clear the cache on restart */
 	wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, 
-				   TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
+				   TDB_DEFAULT /* TDB_CLEAR_IF_FIRST */, O_RDWR|O_CREAT, 0600);
 
 	if (!wcache->tdb) {
 		DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
 	}
+
 	DEBUG(10,("wcache_flush_cache success\n"));
 }
 
@@ -437,10 +439,18 @@
 */
 static BOOL centry_expired(struct winbindd_domain *domain, const char *keystr, struct cache_entry *centry)
 {
+	/* when the domain is offline and we havent checked in the last 30
+	 * seconds if it has become online again, return the cached entry */
+	if (!domain->online && !NT_STATUS_IS_OK(check_negative_conn_cache(domain->name, domain->dcname))) {
+		DEBUG(10,("centry_expired: Key %s for domain %s valid as domain is offline.\n",
+			keystr, domain->name ));
+		return False;
+	}
+
 	/* if the server is OK and our cache entry came from when it was down then
 	   the entry is invalid */
-	if (domain->sequence_number != DOM_SEQUENCE_NONE && 
-	    centry->sequence_number == DOM_SEQUENCE_NONE) {
+	if ((domain->sequence_number != DOM_SEQUENCE_NONE) &&  
+	    (centry->sequence_number == DOM_SEQUENCE_NONE)) {
 		DEBUG(10,("centry_expired: Key %s for domain %s invalid sequence.\n",
 			keystr, domain->name ));
 		return True;
@@ -1640,7 +1650,9 @@
 	return NT_STATUS_OK;
 }
 
-/* enumerate trusted domains */
+/* enumerate trusted domains 
+ * (we need to have the list of trustdoms in the cache when we go offline) -
+ * Guenther */
 static NTSTATUS trusted_domains(struct winbindd_domain *domain,
 				TALLOC_CTX *mem_ctx,
 				uint32 *num_domains,
@@ -1648,14 +1660,82 @@
 				char ***alt_names,
 				DOM_SID **dom_sids)
 {
-	get_cache(domain);
+ 	struct winbind_cache *cache = get_cache(domain);
+ 	struct cache_entry *centry = NULL;
+ 	NTSTATUS status;
+	int i;
+ 
+	if (!cache->tdb)
+		goto do_query;
+ 
+	centry = wcache_fetch(cache, domain, "TRUSTDOMS/%s", domain->name);
+	
+	if (!centry) {
+ 		goto do_query;
+	}
+ 
+	*num_domains = centry_uint32(centry);
+	
+	(*names) 	= TALLOC_ARRAY(mem_ctx, char *, *num_domains);
+	(*alt_names) 	= TALLOC_ARRAY(mem_ctx, char *, *num_domains);
+	(*dom_sids) 	= TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
+ 
+	if (! (*dom_sids) || ! (*names) || ! (*alt_names)) {
+		smb_panic("trusted_domains out of memory");
+ 	}
+ 
+	for (i=0; i<(*num_domains); i++) {
+		(*names)[i] = centry_string(centry, mem_ctx);
+		(*alt_names)[i] = centry_string(centry, mem_ctx);
+		centry_sid(centry, &(*dom_sids)[i]);
+	}
 
+ 	status = centry->status;
+ 
+	DEBUG(10,("trusted_domains: [Cached] - cached info for domain %s status %s\n",
+		domain->name, get_friendly_nt_error_msg(status) ));
+ 
+ 	centry_free(centry);
+ 	return status;
+ 
+do_query:
+	(*num_domains) = 0;
+	(*dom_sids) = NULL;
+	(*names) = NULL;
+	(*alt_names) = NULL;
+ 
+	/* Return status value returned by seq number check */
+
+ 	if (!NT_STATUS_IS_OK(domain->last_status))
+ 		return domain->last_status;
+	
 	DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n",
 		domain->name ));
+ 
+	status = domain->backend->trusted_domains(domain, mem_ctx, num_domains,
+						names, alt_names, dom_sids);
+ 
+	/* and save it */
+	refresh_sequence_number(domain, False);
+ 
+ 	centry = centry_start(domain, status);
+	if (!centry)
+		goto skip_save;
 
-	/* we don't cache this call */
-	return domain->backend->trusted_domains(domain, mem_ctx, num_domains, 
-					       names, alt_names, dom_sids);
+	centry_put_uint32(centry, *num_domains);
+
+	for (i=0; i<(*num_domains); i++) {
+		centry_put_string(centry, (*names)[i]);
+		centry_put_string(centry, (*alt_names)[i]);
+		centry_put_sid(centry, &(*dom_sids)[i]);
+ 	}
+	
+	centry_end(centry, "TRUSTDOMS/%s", domain->name);
+ 
+ 	centry_free(centry);
+ 
+skip_save:
+ 	return status;
 }	
 
 /* get lockout policy */
@@ -1808,8 +1888,9 @@
 	if (wcache->tdb != NULL)
 		return True;
 
+	/* when working offline we must not clear the cache on restart */
 	wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, 
-				   TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
+				   TDB_DEFAULT /*TDB_CLEAR_IF_FIRST*/, O_RDWR|O_CREAT, 0600);
 
 	if (wcache->tdb == NULL) {
 		DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));

Modified: trunk/source/nsswitch/winbindd_cm.c
===================================================================
--- trunk/source/nsswitch/winbindd_cm.c	2005-12-19 02:44:26 UTC (rev 12339)
+++ trunk/source/nsswitch/winbindd_cm.c	2005-12-19 02:50:15 UTC (rev 12340)
@@ -778,14 +778,17 @@
 			addrs[1].sin_port = htons(139);
 			if (!open_any_socket_out(addrs, 2, 10000,
 						 &dummy, &fd)) {
+				domain->online = False;
 				fd = -1;
 			}
 		}
 
 		if ((fd == -1) &&
 		    !find_new_dc(mem_ctx, domain, domain->dcname,
-				 &domain->dcaddr, &fd))
+				 &domain->dcaddr, &fd)) {
+			domain->online = False;
 			break;
+		}
 
 		new_conn->cli = NULL;
 
@@ -796,6 +799,10 @@
 			break;
 	}
 
+	if (NT_STATUS_IS_OK(result)) {
+		domain->online = True;
+	}
+
 	talloc_destroy(mem_ctx);
 	return result;
 }

Modified: trunk/source/nsswitch/winbindd_util.c
===================================================================
--- trunk/source/nsswitch/winbindd_util.c	2005-12-19 02:44:26 UTC (rev 12339)
+++ trunk/source/nsswitch/winbindd_util.c	2005-12-19 02:50:15 UTC (rev 12340)
@@ -162,6 +162,7 @@
 	domain->sequence_number = DOM_SEQUENCE_NONE;
 	domain->last_seq_check = 0;
 	domain->initialized = False;
+	domain->online = False;
 	if (sid) {
 		sid_copy(&domain->sid, sid);
 	}
@@ -335,6 +336,7 @@
 	struct winbindd_request *request;
 	struct winbindd_response *response;
 	struct init_child_state *state;
+	struct winbindd_domain *request_domain;
 
 	mem_ctx = talloc_init("init_child_connection");
 	if (mem_ctx == NULL) {
@@ -367,7 +369,6 @@
 		fstrcpy(request->domain_name, domain->name);
 		request->data.init_conn.is_primary = True;
 		fstrcpy(request->data.init_conn.dcname, "");
-
 		async_request(mem_ctx, &domain->child, request, response,
 			      init_child_recv, state);
 		return WINBINDD_PENDING;
@@ -379,7 +380,11 @@
 	request->cmd = WINBINDD_GETDCNAME;
 	fstrcpy(request->domain_name, domain->name);
 
-	async_domain_request(mem_ctx, find_our_domain(), request, response,
+	/* save online flag */
+	request_domain = find_our_domain();
+	request_domain->online = domain->online;
+	
+	async_domain_request(mem_ctx, request_domain, request, response,
 			     init_child_getdc_recv, state);
 	return WINBINDD_PENDING;
 }



More information about the samba-cvs mailing list