svn commit: samba r20488 - in branches: SAMBA_3_0/source/nsswitch SAMBA_3_0_24/source/nsswitch

jerry at samba.org jerry at samba.org
Tue Jan 2 21:48:49 GMT 2007


Author: jerry
Date: 2007-01-02 21:48:47 +0000 (Tue, 02 Jan 2007)
New Revision: 20488

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

Log:
When joined to a child domain in a multi-domain/single domain tree,
the child domain cannot always resolve SIDs in sibling domains.  
Windows tries to contact a DC in its own domain and then the root 
domain in the forest.  This async changes makes winbindd's name2sid()
call do the same.


Modified:
   branches/SAMBA_3_0/source/nsswitch/winbindd.h
   branches/SAMBA_3_0/source/nsswitch/winbindd_async.c
   branches/SAMBA_3_0/source/nsswitch/winbindd_util.c
   branches/SAMBA_3_0_24/source/nsswitch/winbindd.h
   branches/SAMBA_3_0_24/source/nsswitch/winbindd_async.c
   branches/SAMBA_3_0_24/source/nsswitch/winbindd_util.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/winbindd.h
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd.h	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd.h	2007-01-02 21:48:47 UTC (rev 20488)
@@ -151,6 +151,7 @@
 struct winbindd_domain {
 	fstring name;                          /* Domain name */	
 	fstring alt_name;                      /* alt Domain name (if any) */
+	fstring forest_name;                   /* Name of the AD forest we're in */
 	DOM_SID sid;                           /* SID for this domain */
 	BOOL initialized;		       /* Did we already ask for the domain mode? */
 	BOOL native_mode;                      /* is this a win2k domain in native mode ? */

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_async.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_async.c	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_async.c	2007-01-02 21:48:47 UTC (rev 20488)
@@ -772,7 +772,11 @@
 	return WINBINDD_OK;
 }
 
-static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+/********************************************************************
+ This is the second callback after contacting the forest root
+********************************************************************/
+
+static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
 			    struct winbindd_response *response,
 			    void *c, void *private_data)
 {
@@ -804,8 +808,71 @@
 	     (enum lsa_SidType)response->data.sid.type);
 }
 
-void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name,
-			       const char *name,
+/********************************************************************
+ This is the first callback after contacting our own domain 
+********************************************************************/
+
+static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+			    struct winbindd_response *response,
+			    void *c, void *private_data)
+{
+	void (*cont)(void *priv, BOOL succ, const DOM_SID *sid,
+		     enum lsa_SidType type) =
+		(void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
+	DOM_SID sid;
+
+	if (!success) {
+		DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
+		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+		return;
+	}
+
+	if (response->result != WINBINDD_OK) {
+		/* Try again using the forest root */
+		struct winbindd_domain *root_domain = find_root_domain();
+		struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;		
+		struct winbindd_request request;		
+		char *name_domain, *name_account;
+		
+		if ( !root_domain ) {
+			DEBUG(5,("lookupname_recv: unable determine forest root\n"));
+			cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+			return;
+		}
+
+		name_domain  = state->request.data.name.dom_name;
+		name_account = state->request.data.name.name;	
+
+		ZERO_STRUCT(request);
+		request.cmd = WINBINDD_LOOKUPNAME;
+		fstrcpy(request.data.name.dom_name, name_domain);
+		fstrcpy(request.data.name.name, name_account);
+
+		do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
+				(void *)cont, private_data);
+
+		return;
+	}
+
+	if (!string_to_sid(&sid, response->data.sid.sid)) {
+		DEBUG(0, ("Could not convert string %s to sid\n",
+			  response->data.sid.sid));
+		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+		return;
+	}
+
+	cont(private_data, True, &sid,
+	     (enum lsa_SidType)response->data.sid.type);
+}
+
+/********************************************************************
+ The lookup name call first contacts a DC in its own domain
+ and fallbacks to contact a DC in the forest in our domain doesn't
+ know the name.
+********************************************************************/
+
+void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
+			       const char *dom_name, const char *name,
 			       void (*cont)(void *private_data, BOOL success,
 					    const DOM_SID *sid,
 					    enum lsa_SidType type),
@@ -814,9 +881,7 @@
 	struct winbindd_request request;
 	struct winbindd_domain *domain;
 
-	domain = find_lookup_domain_from_name(dom_name);
-
-	if (domain == NULL) {
+	if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
 		DEBUG(5, ("Could not find domain for name %s\n", dom_name));
 		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
 		return;

Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_util.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_util.c	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_util.c	2007-01-02 21:48:47 UTC (rev 20488)
@@ -529,6 +529,10 @@
 					     &cache_methods, &our_sid);
 		domain->primary = True;
 		setup_domain_child(domain, &domain->child, NULL);
+#if 0	/* old code needed to get the parent domain */
+		init_dc_connection(domain);
+#endif
+		
 		/* Even in the parent winbindd we'll need to
 		   talk to the DC, so try and see if we can
 		   contact it. Theoretically this isn't neccessary
@@ -652,6 +656,19 @@
 	return NULL;
 }
 
+struct winbindd_domain *find_root_domain(void)
+{
+	struct winbindd_domain *ours = find_our_domain();	
+	
+	if ( !ours )
+		return NULL;
+	
+	if ( strlen(ours->forest_name) == 0 )
+		return NULL;
+	
+	return find_domain_from_name( ours->forest_name );
+}
+
 struct winbindd_domain *find_builtin_domain(void)
 {
 	DOM_SID sid;

Modified: branches/SAMBA_3_0_24/source/nsswitch/winbindd.h
===================================================================
--- branches/SAMBA_3_0_24/source/nsswitch/winbindd.h	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0_24/source/nsswitch/winbindd.h	2007-01-02 21:48:47 UTC (rev 20488)
@@ -161,6 +161,7 @@
 struct winbindd_domain {
 	fstring name;                          /* Domain name */	
 	fstring alt_name;                      /* alt Domain name (if any) */
+	fstring forest_name;                   /* Name of the AD forest we're in */
 	DOM_SID sid;                           /* SID for this domain */
 	BOOL initialized;		       /* Did we already ask for the domain mode? */
 	BOOL native_mode;                      /* is this a win2k domain in native mode ? */

Modified: branches/SAMBA_3_0_24/source/nsswitch/winbindd_async.c
===================================================================
--- branches/SAMBA_3_0_24/source/nsswitch/winbindd_async.c	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0_24/source/nsswitch/winbindd_async.c	2007-01-02 21:48:47 UTC (rev 20488)
@@ -633,7 +633,11 @@
 	return WINBINDD_OK;
 }
 
-static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+/********************************************************************
+ This is the second callback after contacting the forest root
+********************************************************************/
+
+static void lookupname_recv2(TALLOC_CTX *mem_ctx, BOOL success,
 			    struct winbindd_response *response,
 			    void *c, void *private_data)
 {
@@ -665,8 +669,71 @@
 	     (enum lsa_SidType)response->data.sid.type);
 }
 
-void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name,
-			       const char *name,
+/********************************************************************
+ This is the first callback after contacting our own domain 
+********************************************************************/
+
+static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
+			    struct winbindd_response *response,
+			    void *c, void *private_data)
+{
+	void (*cont)(void *priv, BOOL succ, const DOM_SID *sid,
+		     enum lsa_SidType type) =
+		(void (*)(void *, BOOL, const DOM_SID *, enum lsa_SidType))c;
+	DOM_SID sid;
+
+	if (!success) {
+		DEBUG(5, ("lookupname_recv: lookup_name() failed!\n"));
+		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+		return;
+	}
+
+	if (response->result != WINBINDD_OK) {
+		/* Try again using the forest root */
+		struct winbindd_domain *root_domain = find_root_domain();
+		struct winbindd_cli_state *state = (struct winbindd_cli_state*)private_data;		
+		struct winbindd_request request;		
+		char *name_domain, *name_account;
+		
+		if ( !root_domain ) {
+			DEBUG(5,("lookupname_recv: unable determine forest root\n"));
+			cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+			return;
+		}
+
+		name_domain  = state->request.data.name.dom_name;
+		name_account = state->request.data.name.name;	
+
+		ZERO_STRUCT(request);
+		request.cmd = WINBINDD_LOOKUPNAME;
+		fstrcpy(request.data.name.dom_name, name_domain);
+		fstrcpy(request.data.name.name, name_account);
+
+		do_async_domain(mem_ctx, root_domain, &request, lookupname_recv2,
+				(void *)cont, private_data);
+
+		return;
+	}
+
+	if (!string_to_sid(&sid, response->data.sid.sid)) {
+		DEBUG(0, ("Could not convert string %s to sid\n",
+			  response->data.sid.sid));
+		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
+		return;
+	}
+
+	cont(private_data, True, &sid,
+	     (enum lsa_SidType)response->data.sid.type);
+}
+
+/********************************************************************
+ The lookup name call first contacts a DC in its own domain
+ and fallbacks to contact a DC in the forest in our domain doesn't
+ know the name.
+********************************************************************/
+
+void winbindd_lookupname_async(TALLOC_CTX *mem_ctx,
+			       const char *dom_name, const char *name,
 			       void (*cont)(void *private_data, BOOL success,
 					    const DOM_SID *sid,
 					    enum lsa_SidType type),
@@ -675,9 +742,7 @@
 	struct winbindd_request request;
 	struct winbindd_domain *domain;
 
-	domain = find_lookup_domain_from_name(dom_name);
-
-	if (domain == NULL) {
+	if ( (domain = find_lookup_domain_from_name(dom_name)) == NULL ) {
 		DEBUG(5, ("Could not find domain for name %s\n", dom_name));
 		cont(private_data, False, NULL, SID_NAME_UNKNOWN);
 		return;

Modified: branches/SAMBA_3_0_24/source/nsswitch/winbindd_util.c
===================================================================
--- branches/SAMBA_3_0_24/source/nsswitch/winbindd_util.c	2007-01-02 21:45:12 UTC (rev 20487)
+++ branches/SAMBA_3_0_24/source/nsswitch/winbindd_util.c	2007-01-02 21:48:47 UTC (rev 20488)
@@ -529,6 +529,10 @@
 					     &cache_methods, &our_sid);
 		domain->primary = True;
 		setup_domain_child(domain, &domain->child, NULL);
+#if 0	/* old code needed to get the parent domain */
+		init_dc_connection(domain);
+#endif
+		
 		/* Even in the parent winbindd we'll need to
 		   talk to the DC, so try and see if we can
 		   contact it. Theoretically this isn't neccessary
@@ -652,6 +656,19 @@
 	return NULL;
 }
 
+struct winbindd_domain *find_root_domain(void)
+{
+	struct winbindd_domain *ours = find_our_domain();	
+	
+	if ( !ours )
+		return NULL;
+	
+	if ( strlen(ours->forest_name) == 0 )
+		return NULL;
+	
+	return find_domain_from_name( ours->forest_name );
+}
+
 struct winbindd_domain *find_builtin_domain(void)
 {
 	DOM_SID sid;



More information about the samba-cvs mailing list