summaryrefslogtreecommitdiff
path: root/source3/nsswitch
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 /source3/nsswitch
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)
Diffstat (limited to 'source3/nsswitch')
-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;