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