winbindd offline startup state.

Jeremy Allison jra at samba.org
Fri Oct 6 05:59:02 GMT 2006


The attached patch is how I think winbindd should
be dealing with starting up in a disconnected state.

I've made set_dc_type_and_flags() static and made it
called from init_dc_connection() only when init_dc_connection
knows it has a valid handle to the DC.

I've removed the connection part of it so it can assume a
valid set of handles and just call the "get dc type"
functions.

The side effect is that domain->initialized doesn't
get set until we have a successful connection to a
DC and we've asked it questions :-).

I think this is correct but I'm not checking it in
yet as without testing it'll probably break winbindd
in SAMBA_3_0 (I'm suspicious of the dual daemon startup
methods).

I'm going to be up early tomorrow (6am conf call) but
just wanted to give you all a heads up on what I'll be
doing to finish this tomorrow morning. (Gd this is
mainly for you so you don't waste time on the bug).

Just wanted to get this where people can look at it !

Cheers,

	Jeremy.
-------------- next part --------------
Index: nsswitch/winbindd_cm.c
===================================================================
--- nsswitch/winbindd_cm.c	(revision 19110)
+++ nsswitch/winbindd_cm.c	(working copy)
@@ -64,7 +64,7 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
-static NTSTATUS init_dc_connection(struct winbindd_domain *domain);
+static void set_dc_type_and_flags( struct winbindd_domain *domain );
 
 /****************************************************************
  Handler triggered if we're offline to try and detect a DC.
@@ -175,24 +175,27 @@
 	/* If we are waiting to get a krb5 ticket, trigger immediately. */
 	GetTimeOfDay(&now);
 	set_event_dispatch_time("krb5_ticket_gain_handler", now);
-	domain->online = True;
 
 	/* Ok, we're out of any startup mode now... */
 	domain->startup = False;
 
-	/* We were offline - now we're online. We default to
-	   using the MS-RPC backend if we started offline,
-	   and if we're going online for the first time we
-	   should really re-initialize the backends and the
-	   checks to see if we're talking to an AD or NT domain.
-	*/
+	if (domain->online == False) {
+		/* We were offline - now we're online. We default to
+		   using the MS-RPC backend if we started offline,
+		   and if we're going online for the first time we
+		   should really re-initialize the backends and the
+		   checks to see if we're talking to an AD or NT domain.
+		*/
 
-	domain->initialized = False;
+		domain->initialized = False;
 
-	/* 'reconnect_methods' is the MS-RPC backend. */
-	if (domain->backend == &reconnect_methods) {
-		domain->backend = NULL;
+		/* 'reconnect_methods' is the MS-RPC backend. */
+		if (domain->backend == &reconnect_methods) {
+			domain->backend = NULL;
+		}
 	}
+
+	domain->online = True;
 }
 
 /****************************************************************
@@ -1178,17 +1181,29 @@
 
 	return True;
 }
-	
+
 /* Initialize a new connection up to the RPC BIND. */
 
-static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
+NTSTATUS init_dc_connection(struct winbindd_domain *domain)
 {
-	if (connection_ok(domain))
+	NTSTATUS result;
+
+	if (connection_ok(domain)) {
+		if (!domain->initialized) {
+			set_dc_type_and_flags(domain);
+		}
 		return NT_STATUS_OK;
+	}
 
 	invalidate_cm_connection(&domain->conn);
 
-	return cm_open_connection(domain, &domain->conn);
+	result = cm_open_connection(domain, &domain->conn);
+
+	if (NT_STATUS_IS_OK(result) && !domain->initialized) {
+		set_dc_type_and_flags(domain);
+	}
+
+	return result;
 }
 
 /******************************************************************************
@@ -1199,7 +1214,7 @@
  is native mode.
 ******************************************************************************/
 
-void set_dc_type_and_flags( struct winbindd_domain *domain )
+static void set_dc_type_and_flags( struct winbindd_domain *domain )
 {
 	NTSTATUS 		result;
 	DS_DOMINFO_CTR		ctr;
@@ -1210,28 +1225,20 @@
 	char *domain_name = NULL;
 	char *dns_name = NULL;
 	DOM_SID *dom_sid = NULL;
-	int try_count = 0;
 
 	ZERO_STRUCT( ctr );
 	
-	domain->native_mode = False;
-	domain->active_directory = False;
-
 	if (domain->internal) {
 		domain->initialized = True;
 		return;
 	}
 
-  try_again:
-
-	result = init_dc_connection(domain);
-	if (!NT_STATUS_IS_OK(result) || try_count > 2) {
-		DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
-			  "to %s: (%s)\n", domain->name, nt_errstr(result)));
-		domain->initialized = True;
+	if (!connection_ok(domain)) {
 		return;
 	}
 
+	DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
+
 	cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
 				       &result);
 
@@ -1239,10 +1246,7 @@
 		DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
 			  "PI_LSARPC_DS on domain %s: (%s)\n",
 			  domain->name, nt_errstr(result)));
-		domain->initialized = True;
-		/* We want to detect network failures asap to try another dc. */
-		try_count++;
-		goto try_again;
+		return;
 	}
 
 	result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
@@ -1251,21 +1255,27 @@
 	cli_rpc_pipe_close(cli);
 
 	if (!NT_STATUS_IS_OK(result)) {
-		domain->initialized = True;
+		DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
+			  "on domain %s failed: (%s)\n",
+			  domain->name, nt_errstr(result)));
 		return;
 	}
 	
 	if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
-	    !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
+	    !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
 		domain->native_mode = True;
+	} else {
+		domain->native_mode = False;
+	}
 
 	cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
 
 	if (cli == NULL) {
-		domain->initialized = True;
-		/* We want to detect network failures asap to try another dc. */
-		try_count++;
-		goto try_again;
+		DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
+			  "PI_LSARPC on domain %s: (%s)\n",
+			  domain->name, nt_errstr(result)));
+		cli_rpc_pipe_close(cli);
+		return;
 	}
 
 	mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
@@ -1289,6 +1299,8 @@
 	}
 
 	if (NT_STATUS_IS_OK(result)) {
+		domain->active_directory = True;
+
 		if (domain_name)
 			fstrcpy(domain->name, domain_name);
 
@@ -1297,10 +1309,9 @@
 
 		if (dom_sid) 
 			sid_copy(&domain->sid, dom_sid);
+	} else {
+		domain->active_directory = False;
 
-		domain->active_directory = True;
-	} else {
-		
 		result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
 						SEC_RIGHTS_MAXIMUM_ALLOWED,
 						&pol);
@@ -1322,13 +1333,17 @@
 	}
 done:
 
+	DEBUG(5, ("set_dc_type_and_flags: domain %s is %snative mode.\n",
+		  domain->name, domain->native_mode ? "" : "NOT "));
+
+	DEBUG(5,("set_dc_type_and_flags: domain %s is %sactive directory.\n",
+		  domain->name, domain->active_directory ? "" : "NOT "));
+
 	cli_rpc_pipe_close(cli);
 	
 	talloc_destroy(mem_ctx);
 
 	domain->initialized = True;
-	
-	return;
 }
 
 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
Index: nsswitch/winbindd_util.c
===================================================================
--- nsswitch/winbindd_util.c	(revision 19110)
+++ nsswitch/winbindd_util.c	(working copy)
@@ -474,7 +474,7 @@
 		domain->dcaddr.sin_port = 0;
 	}
 
-	set_dc_type_and_flags(domain);
+	init_dc_connection(domain);
 
 	if (!domain->initialized) {
 		DEBUG(1, ("Could not initialize domain %s\n",
@@ -585,7 +585,7 @@
 		return NULL;
 
 	if (!domain->initialized)
-		set_dc_type_and_flags(domain);
+		init_dc_connection(domain);
 
 	return domain;
 }
@@ -620,7 +620,7 @@
 		return NULL;
 
 	if (!domain->initialized)
-		set_dc_type_and_flags(domain);
+		init_dc_connection(domain);
 
 	return domain;
 }
Index: nsswitch/winbindd_cache.c
===================================================================
--- nsswitch/winbindd_cache.c	(revision 19110)
+++ nsswitch/winbindd_cache.c	(working copy)
@@ -90,7 +90,7 @@
 	/* we have to know what type of domain we are dealing with first */
 
 	if ( !domain->initialized )
-		set_dc_type_and_flags( domain );
+		init_dc_connection( domain );
 
 	/* 
 	   OK.  listen up becasue I'm only going to say this once.
Index: nsswitch/winbindd_pam.c
===================================================================
--- nsswitch/winbindd_pam.c	(revision 19110)
+++ nsswitch/winbindd_pam.c	(working copy)
@@ -1006,7 +1006,7 @@
 	}
 
 	if (!contact_domain->initialized) {
-		set_dc_type_and_flags(contact_domain);
+		init_dc_connection(contact_domain);
 	}
 
 	if (!contact_domain->active_directory) {
@@ -1217,7 +1217,7 @@
 			"request in startup mode.\n", domain->name ));
 
 		winbindd_flush_negative_conn_cache(domain);
-		set_dc_type_and_flags(domain);
+		init_dc_connection(domain);
 	}
 
 	DEBUG(10,("winbindd_dual_pam_auth: domain: %s last was %s\n", domain->name, domain->online ? "online":"offline"));


More information about the samba-technical mailing list