svn commit: samba r21616 - in branches/SAMBA_3_0/source/nsswitch: .

jerry at samba.org jerry at samba.org
Thu Mar 1 03:16:38 GMT 2007


Author: jerry
Date: 2007-03-01 03:16:38 +0000 (Thu, 01 Mar 2007)
New Revision: 21616

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

Log:
Delay initialization of idmap and nss_info backends until necessary
so they can honor the offline logon state.


Modified:
   branches/SAMBA_3_0/source/nsswitch/idmap.c
   branches/SAMBA_3_0/source/nsswitch/idmap_cache.c
   branches/SAMBA_3_0/source/nsswitch/nss_info.c
   branches/SAMBA_3_0/source/nsswitch/winbindd.c
   branches/SAMBA_3_0/source/nsswitch/winbindd_async.c
   branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/idmap.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/idmap.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/idmap.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -225,9 +225,36 @@
 
 static const char *idmap_default_domain[] = { "default domain", NULL };
 
+/****************************************************************************
+ ****************************************************************************/
+
+NTSTATUS idmap_init_cache(void)
+{	
+	/* Always initialize the cache.  We'll have to delay initialization
+	   of backends if we are offline */
+
+	if ( idmap_ctx ) {
+		return NT_STATUS_OK;
+	}	
+	
+	if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ ****************************************************************************/
+
 NTSTATUS idmap_init(void)
 {	
 	NTSTATUS ret;
+	static NTSTATUS backend_init_status = NT_STATUS_UNSUCCESSFUL;	
 	struct idmap_domain *dom;
 	char *compat_backend = NULL;
 	char *compat_params = NULL;
@@ -238,18 +265,25 @@
 	int compat = 0;
 	int i;
 
-	if (idmap_ctx) {
+	/* Always initialize the cache.  We'll have to delay initialization
+	   of backends if we are offline */
+
+	ret = idmap_init_cache();
+	if ( !NT_STATUS_IS_OK(ret) )
+		return ret;
+
+	if ( NT_STATUS_IS_OK(backend_init_status) ) {
 		return NT_STATUS_OK;
 	}
+	
+	/* We can't reliably call intialization code here unless 
+	   we are online */
 
-	if ( (idmap_ctx = talloc_named_const(NULL, 0, "idmap_ctx")) == NULL ) {
-		return NT_STATUS_NO_MEMORY;
+	if ( get_global_winbindd_state_offline() ) {
+		backend_init_status = NT_STATUS_FILE_IS_OFFLINE;
+		return backend_init_status;		
 	}
 
-	if ( (idmap_cache = idmap_cache_init(idmap_ctx)) == NULL ) {
-		return NT_STATUS_UNSUCCESSFUL;
-	}
-
 	static_init_idmap;
 
 	dom_list = lp_idmap_domains();
@@ -559,11 +593,17 @@
 	/* cleanpu temporary strings */
 	TALLOC_FREE( compat_backend );
 	
+	backend_init_status = NT_STATUS_OK;
+	
 	return NT_STATUS_OK;
 
 done:
 	DEBUG(0, ("Aborting IDMAP Initialization ...\n"));
 	idmap_close();
+
+	/* save the init status for later checks */
+	backend_init_status = ret;
+	
 	return ret;
 }
 
@@ -1067,6 +1107,14 @@
 
 	/* let's see if there is any id mapping to be retieved from the backends */
 	if (bi) {
+		/* Only do query if we are online */
+		if ( lp_winbind_offline_logon() &&
+		     get_global_winbindd_state_offline() )
+		{
+			ret = NT_STATUS_FILE_IS_OFFLINE;
+			goto done;
+		}
+
 		ret = idmap_backends_unixids_to_sids(bids);
 		IDMAP_CHECK_RET(ret);
 
@@ -1132,7 +1180,8 @@
 		if ( ! NT_STATUS_IS_OK(ret)) {
 
 			if ( ! bids) {
-				/* alloc space for ids to be resolved by backends (realloc ten by ten) */
+				/* alloc space for ids to be resolved
+				   by backends (realloc ten by ten) */
 				bids = talloc_array(ctx, struct id_map *, 10);
 				if ( ! bids) {
 					DEBUG(1, ("Out of memory!\n"));
@@ -1164,6 +1213,14 @@
 
 	/* let's see if there is any id mapping to be retieved from the backends */
 	if (bids) {
+		/* Only do query if we are online */
+		if ( lp_winbind_offline_logon() &&
+		     get_global_winbindd_state_offline() )
+		{
+			ret = NT_STATUS_FILE_IS_OFFLINE;
+			goto done;
+		}
+		
 		ret = idmap_backends_sids_to_unixids(bids);
 		IDMAP_CHECK_RET(ret);
 

Modified: branches/SAMBA_3_0/source/nsswitch/idmap_cache.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/idmap_cache.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/idmap_cache.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -22,6 +22,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/
 
 #include "includes.h"
+#include "winbindd.h"
 
 #define TIMEOUT_LEN 12
 #define IDMAP_CACHE_DATA_FMT	"%12u/%s"
@@ -418,14 +419,34 @@
 		/* here ret == NT_STATUS_OK and id->status = ID_MAPPED */
 
 		if (t <= time(NULL)) {
-			/* We're expired, set an error code for upper layer */
-			ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+			/* If we've been told to be offline - stay in 
+			   that state... */
+			if (lp_winbind_offline_logon() && 
+			    get_global_winbindd_state_offline()) 
+			{
+				DEBUG(10,("idmap_cache_map_sid: winbindd is "
+					  "globally offline.\n"));
+			} else {
+				/* We're expired, set an error code
+				   for upper layer */
+				ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+			}			
 		}
 	} else {
 		if (t <= time(NULL)) {
-			/* We're expired, delete the entry and return not mapped */
-			tdb_delete(cache->tdb, keybuf);
-			ret = NT_STATUS_NONE_MAPPED;
+			/* If we've been told to be offline - stay in 
+			   that state... */
+			if (lp_winbind_offline_logon() && 
+			    get_global_winbindd_state_offline()) 
+			{
+				DEBUG(10,("idmap_cache_map_sid: winbindd is "
+					  "globally offline.\n"));
+			} else {				
+				/* We're expired, delete the entry and return
+				   not mapped */
+				tdb_delete(cache->tdb, keybuf);
+				ret = NT_STATUS_NONE_MAPPED;
+			}			
 		} else {
 			/* this is not mapped as it was a negative cache hit */
 			id->status = ID_UNMAPPED;
@@ -508,14 +529,34 @@
 		/* here ret == NT_STATUS_OK and id->mapped = True */
 
 		if (t <= time(NULL)) {
-			/* We're expired, set an error code for upper layer */
-			ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+			/* If we've been told to be offline - stay in
+			   that state... */
+			if (lp_winbind_offline_logon() && 
+			    get_global_winbindd_state_offline()) 
+			{
+				DEBUG(10,("idmap_cache_map_sid: winbindd is "
+					  "globally offline.\n"));
+			} else {
+				/* We're expired, set an error code
+				   for upper layer */
+				ret = NT_STATUS_SYNCHRONIZATION_REQUIRED;
+			}			
 		}
 	} else {
 		if (t <= time(NULL)) {
-			/* We're expired, delete the entry and return not mapped */
-			tdb_delete(cache->tdb, keybuf);
-			ret = NT_STATUS_NONE_MAPPED;
+			/* If we've been told to be offline - stay in
+			   that state... */
+			if (lp_winbind_offline_logon() && 
+			    get_global_winbindd_state_offline()) 
+			{
+				DEBUG(10,("idmap_cache_map_sid: winbindd is "
+					  "globally offline.\n"));
+			} else {
+				/* We're expired, delete the entry and
+				   return not mapped */
+				tdb_delete(cache->tdb, keybuf);
+				ret = NT_STATUS_NONE_MAPPED;
+			}			
 		} else {
 			/* this is not mapped is it was a negative cache hit */
 			id->status = ID_UNMAPPED;

Modified: branches/SAMBA_3_0/source/nsswitch/nss_info.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/nss_info.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/nss_info.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -131,11 +131,17 @@
  NTSTATUS nss_init( const char **nss_list )
 {
 	NTSTATUS status;
+	static NTSTATUS nss_initialized = NT_STATUS_UNSUCCESSFUL;
 	int i;
 	char *backend, *domain;
 	struct nss_function_entry *nss_backend;
 	struct nss_domain_entry *nss_domain;
 
+	/* check for previous successful initializations */
+
+	if ( NT_STATUS_IS_OK(nss_initialized) )
+		return NT_STATUS_OK;
+	
 	/* The "template" backend should alqays be registered as it
 	   is a static module */
 
@@ -207,20 +213,25 @@
 	}
 	
 		
+	nss_initialized = NT_STATUS_OK;
+	
 	return NT_STATUS_OK;
 }
 
 /********************************************************************
  *******************************************************************/
 
- NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
-		       TALLOC_CTX *ctx,
-		       ADS_STRUCT *ads, LDAPMessage *msg,
-		       char **homedir, char **shell, char **gecos,
-		       gid_t *p_gid)
+static struct nss_domain_entry *find_nss_domain( const char *domain )
 {
+	NTSTATUS status;	
 	struct nss_domain_entry *p;
-	struct nss_info_methods *m;
+
+	status = nss_init( lp_winbind_nss_info() );
+	if ( !NT_STATUS_IS_OK(status) ) {
+		DEBUG(4,("nss_get_info: Failed to init nss_info API (%s)!\n",
+			 nt_errstr(status)));
+		return NULL;
+	}
 	
 	for ( p=nss_domain_list; p; p=p->next ) {
 		if ( strequal( p->domain, domain ) )
@@ -231,12 +242,33 @@
 
 	if ( !p ) {
 		if ( !nss_domain_list ) {
-			return NT_STATUS_NOT_FOUND;
+			return NULL;
 		}
 		
 		p = nss_domain_list;		
 	}
 
+	return p;
+}
+
+/********************************************************************
+ *******************************************************************/
+
+ NTSTATUS nss_get_info( const char *domain, const DOM_SID *user_sid,
+		       TALLOC_CTX *ctx,
+		       ADS_STRUCT *ads, LDAPMessage *msg,
+		       char **homedir, char **shell, char **gecos,
+		       gid_t *p_gid)
+{
+	struct nss_domain_entry *p;
+	struct nss_info_methods *m;
+
+	if ( (p = find_nss_domain( domain )) == NULL ) {
+		DEBUG(4,("nss_get_info: Failed to find nss domain pointer for %s\n",
+			 domain ));
+		return NT_STATUS_NOT_FOUND;
+	}
+		
 	m = p->backend->methods;
 
 	return m->get_nss_info( p, user_sid, ctx, ads, msg, 

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -1011,14 +1011,10 @@
 
 	/* Winbind daemon initialisation */
 
-	if ( ! NT_STATUS_IS_OK(idmap_init()) ) {
-		DEBUG(1, ("Could not init idmap! - Sid/[UG]id mapping will not be available\n"));
+	if ( ! NT_STATUS_IS_OK(idmap_init_cache()) ) {
+		DEBUG(1, ("Could not init idmap cache!\n"));		
 	}
 
-#ifdef WITH_ADS
-	nss_init( lp_winbind_nss_info() );
-#endif
-
 	/* Unblock all signals we are interested in as they may have been
 	   blocked by the parent process. */
 
@@ -1047,6 +1043,7 @@
 
 	pidfile_create("winbindd");
 
+#if 0	/* not finished yet */
 	/* Ensure all cache and idmap caches are consistent
 	   before we startup. */
 
@@ -1060,6 +1057,7 @@
 		}
 		return execve(argv[0], argv, envp);
 	}
+#endif
 
 #if HAVE_SETPGID
 	/*

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_async.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_async.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_async.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -535,7 +535,7 @@
 	request.cmd = WINBINDD_DUAL_SID2GID;
 	sid_to_string(request.data.dual_sid2id.sid, sid);
 
-	DEBUG(7,("idmap_sid2gid_async: Resolving %s to a gid\n", 
+	DEBUG(7,("winbindd_sid2gid_async: Resolving %s to a gid\n", 
 		request.data.dual_sid2id.sid));
 
 	do_async(mem_ctx, idmap_child(), &request, winbindd_sid2gid_recv,

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c	2007-03-01 03:15:22 UTC (rev 21615)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_dual.c	2007-03-01 03:16:38 UTC (rev 21616)
@@ -502,10 +502,26 @@
 		}
 		DEBUG(5,("winbind_msg_offline: marking %s offline.\n", domain->name));
 		set_domain_offline(domain);
+
+		/* Send an offline message to the idmap child when our
+		   primary domain goes offline */
+
+		if ( domain->primary ) {
+			struct winbindd_child *idmap = idmap_child();
+
+			if ( idmap->pid != 0 ) {
+				message_send_pid(pid_to_procid(idmap->pid), 
+						 MSG_WINBIND_OFFLINE, 
+						 domain->name, 
+						 strlen(domain->name)+1, 
+						 False);
+			}			
+		}
 	}
 
 	for (child = children; child != NULL; child = child->next) {
-		/* Don't send message to idmap child. */
+		/* Don't send message to idmap child.  We've already
+		   done so above. */
 		if (!child->domain || (child == idmap_child())) {
 			continue;
 		}
@@ -556,6 +572,22 @@
 
 		winbindd_flush_negative_conn_cache(domain);
 		set_domain_online_request(domain);
+
+		/* Send an offline message to the idmap child when our
+		   primary domain goes offline */
+
+		if ( domain->primary ) {
+			struct winbindd_child *idmap = idmap_child();
+			
+			if ( idmap->pid != 0 ) {
+				message_send_pid(pid_to_procid(idmap->pid), 
+						 MSG_WINBIND_ONLINE,
+						 domain->name,
+						 strlen(domain->name)+1, 
+						 False);
+			}
+			
+		}
 	}
 
 	for (child = children; child != NULL; child = child->next) {



More information about the samba-cvs mailing list