summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2007-01-02 21:48:47 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:16:52 -0500
commitb2317c097954844af4a0596fea507f0139d14465 (patch)
treea718a8529cbb1b93845a0880ab2c96162e3019d4
parentd3fc370fb9e32b881bb6c626ac525246af665ea4 (diff)
downloadsamba-b2317c097954844af4a0596fea507f0139d14465.tar.gz
samba-b2317c097954844af4a0596fea507f0139d14465.tar.bz2
samba-b2317c097954844af4a0596fea507f0139d14465.zip
r20488: 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. (This used to be commit 7b2bf0e5a6b8d4119657c7a34aa53c9a0c1d5723)
-rw-r--r--source3/nsswitch/winbindd.h1
-rw-r--r--source3/nsswitch/winbindd_async.c77
-rw-r--r--source3/nsswitch/winbindd_util.c17
3 files changed, 89 insertions, 6 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index b62cc0af19..59557c4942 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -151,6 +151,7 @@ struct winbindd_child {
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 ? */
diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c
index 913cfdecc5..7bedd5a0fd 100644
--- a/source3/nsswitch/winbindd_async.c
+++ b/source3/nsswitch/winbindd_async.c
@@ -772,7 +772,11 @@ enum winbindd_result winbindd_dual_lookupsid(struct winbindd_domain *domain,
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 @@ static void lookupname_recv(TALLOC_CTX *mem_ctx, BOOL success,
(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 @@ void winbindd_lookupname_async(TALLOC_CTX *mem_ctx, const char *dom_name,
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;
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index d0a59b0cbe..419c80e3c4 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -529,6 +529,10 @@ BOOL init_domain_list(void)
&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 @@ struct winbindd_domain *find_our_domain(void)
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;