From 84a50e21541e4c3a0bfb70d5d501dc4b7e6f9714 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 4 Jan 2008 13:35:41 -0600 Subject: Fix the inherited trust flags when spidering the trust heirarchy. Also *do not* clear the trust list when rescanning or else it is possible to suffer from a race condition where no trusted domains can be found. (This used to be commit e7164a252bf213a74d6eeac5aa04645eed5be241) --- source3/winbindd/winbindd_util.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 70468b6bcd..cc12d4b7ea 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -500,9 +500,13 @@ void rescan_trusted_domains( void ) ((now-last_trustdom_scan) < WINBINDD_RESCAN_FREQ) ) return; - /* clear the TRUSTDOM cache first */ - - wcache_tdc_clear(); + /* I use to clear the cache here and start over but that + caused problems in child processes that needed the + trust dom list early on. Removing it means we + could have some trusted domains listed that have been + removed from our primary domain's DC until a full + restart. This should be ok since I think this is what + Windows does as well. */ /* this will only add new domains we didn't already know about in the domain_list()*/ -- cgit From f3603d5a5ab878d45b67bf0f33e2beca50d0af2d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 00:11:31 +0100 Subject: Convert add_sid_to_array() add_sid_to_array_unique() to return NTSTATUS. Michael (This used to be commit 6b2b9a60ef857ec31da5fea631535205fbdede4a) --- source3/winbindd/winbindd_util.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index cc12d4b7ea..dc48fdef8b 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1304,19 +1304,22 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, /* always add the primary group to the sid array */ sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); - if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { + status = add_sid_to_array(mem_ctx, &primary_group, user_sids, + &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } for (i=0; inum_groups; i++) { sid_copy(&group_sid, &info3->dom_sid.sid); sid_append_rid(&group_sid, info3->gids[i].g_rid); - if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, - &num_groups)) { + status = add_sid_to_array(mem_ctx, &group_sid, user_sids, + &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } } @@ -1328,11 +1331,11 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE) continue; - if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, - user_sids, &num_groups)) - { + status = add_sid_to_array(mem_ctx, &info3->other_sids[i].sid, + user_sids, &num_groups); + if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(info3); - return NT_STATUS_NO_MEMORY; + return status; } } -- cgit From 3b83f4915885edfe8f01f4f68daad6b909fe473d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 23 Jan 2008 13:52:42 +0100 Subject: Initialize _domain_list to NULL. Just to be sure the "if (!_domain_list)" in domain_list() test always works. Michael (This used to be commit 1f49065d44dd7570d5a9928359751bd36f287952) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index dc48fdef8b..0381053331 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -41,7 +41,7 @@ extern struct winbindd_methods passdb_methods; individual winbindd_domain structures cannot be made. Keep a copy of the domain name instead. */ -static struct winbindd_domain *_domain_list; +static struct winbindd_domain *_domain_list = NULL; /** When was the last scan of trusted domains done? -- cgit From 614ba32b221aee268b86033ee10da4dbdb087365 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 24 Jan 2008 22:47:49 +0100 Subject: Fix assignment to request->data.init_conn.is_primary in init_child_connection(). The present assignment "request->data.init_conn.is_primary = domain->internal ? False : True" simply feels wrong. This seems to be the thing right to do: "request->data.init_conn.is_primary = domain->primary ? true : false". The question is: Does this have any purpose at all? data.init_conn.is_primary seems to be used nowhere in the whole code at all. Is it (still) needed? Michael (This used to be commit 8bb21b8b3802e7b093a3c4fb41b8550033388878) --- source3/winbindd/winbindd_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 0381053331..724cce2512 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -571,7 +571,7 @@ enum winbindd_result init_child_connection(struct winbindd_domain *domain, /* The primary domain has to find the DC name itself */ request->cmd = WINBINDD_INIT_CONNECTION; fstrcpy(request->domain_name, domain->name); - request->data.init_conn.is_primary = domain->internal ? False : True; + request->data.init_conn.is_primary = domain->primary ? true : false; fstrcpy(request->data.init_conn.dcname, ""); async_request(mem_ctx, &domain->child, request, response, init_child_recv, state); -- cgit From 2a542ce7727cf3eb7f64d855c70d974f02185a2a Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 24 Jan 2008 22:15:33 +0100 Subject: Add a debug message winbindd_can_contact_domain() explaining the reason for failure. Michael (This used to be commit ba5373ed7f74d560a9de8620039b596b8938d1dc) --- source3/winbindd/winbindd_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 724cce2512..3d9ede3cdf 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1404,6 +1404,8 @@ bool winbindd_can_contact_domain( struct winbindd_domain *domain ) if ( domain->active_directory && ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) { + DEBUG(10, ("Domain is an AD domain and we have no inbound " + "trust.\n")); return False; } -- cgit From 3ca606731b99754493ab5a8d761225c637bc82dd Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 25 Jan 2008 16:40:17 +0100 Subject: Fix winbindd_can_contact_domain() on a samba DC. The check for inbound trusts is invalid when samba is a DC and has a trust with an active directory domain. This effectively prevented tusts with an AD domain on a samba DC from working (unless using "winbindd rpc only"), because an ads_connect() was never performed. Only the rpc-based winbindd methods were working properly. Jerry: Please check! Michael (This used to be commit dcd42a1e0642c69348adfaeecef7f7f2f074ac30) --- source3/winbindd/winbindd_util.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 3d9ede3cdf..d16b7423a1 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1398,10 +1398,13 @@ bool winbindd_can_contact_domain( struct winbindd_domain *domain ) if ( domain->domain_flags & DS_DOMAIN_IN_FOREST ) return True; - /* We cannot contact the domain if it is running AD and - we have no inbound trust */ + /* + * On a _member_ server, we cannot contact the domain if it + * is running AD and we have no inbound trust. + */ - if ( domain->active_directory && + if ( !IS_DC && + domain->active_directory && ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) { DEBUG(10, ("Domain is an AD domain and we have no inbound " -- cgit From 235deb1b66ccfb4a264010e8ffe11a3a3682ac0d Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Fri, 25 Jan 2008 12:21:14 -0600 Subject: Always trust the domain flags in the wcache trusted domain cache. Use the flags stored in the tdb when determining if a domain can be contacted. The tdb should be considered authoratative anyways unless you know the flags in the winbindd_domain are correct (such as when first enumerating trusts). Original suggestion and patch from Steven Danneman . Manually rewritten by me for 3.2. (This used to be commit f53658a20de07a29abbe2e90917b328d00fc0024) --- source3/winbindd/winbindd_util.c | 46 ++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 13 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index d16b7423a1..f6bb5750ea 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1386,36 +1386,56 @@ void ws_name_return( char *name, char replace ) /********************************************************************* ********************************************************************/ -bool winbindd_can_contact_domain( struct winbindd_domain *domain ) +bool winbindd_can_contact_domain(struct winbindd_domain *domain) { + struct winbindd_tdc_domain *tdc = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + bool ret = false; + /* We can contact the domain if it is our primary domain */ - if ( domain->primary ) - return True; + if (domain->primary) { + return true; + } - /* Can always contact a domain that is in out forest */ + /* Trust the TDC cache and not the winbindd_domain flags */ - if ( domain->domain_flags & DS_DOMAIN_IN_FOREST ) - return True; + if ((tdc = wcache_tdc_fetch_domain(frame, domain->name)) == NULL) { + DEBUG(10,("winbindd_can_contact_domain: %s not found in cache\n", + domain->name)); + return false; + } + + /* Can always contact a domain that is in out forest */ + if (tdc->trust_flags & DS_DOMAIN_IN_FOREST) { + ret = true; + goto done; + } + /* * On a _member_ server, we cannot contact the domain if it * is running AD and we have no inbound trust. */ - if ( !IS_DC && + if (!IS_DC && domain->active_directory && - ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) ) + ((tdc->trust_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND)) { - DEBUG(10, ("Domain is an AD domain and we have no inbound " - "trust.\n")); - return False; + DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain " + "and we have no inbound trust.\n", domain->name)); + goto done; } - + /* Assume everything else is ok (probably not true but what can you do?) */ + + ret = true; + +done: + talloc_destroy(frame); - return True; + return ret; } /********************************************************************* -- cgit From 80b2e330f939d9877352f8fbdbec3a4e0e395c7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 29 Jan 2008 17:49:38 +0100 Subject: Remove include/rpc_ds.h and all references to it completly. Jerry, please have a look if you're fine with that. Guenther (This used to be commit beae25c808a3a03d645f247e9befcd05e3ecca2c) --- source3/winbindd/winbindd_util.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/winbindd/winbindd_util.c') diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index f6bb5750ea..10779cd60a 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -218,7 +218,7 @@ static void add_trusted_domains( struct winbindd_domain *domain ) TALLOC_CTX *mem_ctx; struct winbindd_request *request; struct winbindd_response *response; - uint32 fr_flags = (DS_DOMAIN_TREE_ROOT|DS_DOMAIN_IN_FOREST); + uint32 fr_flags = (NETR_TRUST_FLAG_TREEROOT|NETR_TRUST_FLAG_IN_FOREST); struct trustdom_state *state; @@ -391,8 +391,8 @@ static void rescan_forest_root_trusts( void ) the domain_list() as our primary domain may not have been initialized. */ - if ( !(dom_list[i].trust_flags & DS_DOMAIN_TREE_ROOT) ) { - continue; + if ( !(dom_list[i].trust_flags & NETR_TRUST_FLAG_TREEROOT) ) { + continue; } /* Here's the forest root */ @@ -456,10 +456,10 @@ static void rescan_forest_trusts( void ) if ( d && (d->internal || d->primary ) ) continue; - - if ( (flags & DS_DOMAIN_DIRECT_INBOUND) && - (type == DS_DOMAIN_TRUST_TYPE_UPLEVEL) && - (attribs == DS_DOMAIN_TRUST_ATTRIB_FOREST_TRANSITIVE) ) + + if ( (flags & NETR_TRUST_FLAG_INBOUND) && + (type == NETR_TRUST_TYPE_UPLEVEL) && + (attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) ) { /* add the trusted domain if we don't know about it */ @@ -770,8 +770,8 @@ void check_domain_trusted( const char *name, const DOM_SID *user_sid ) forest trust */ domain->active_directory = True; - domain->domain_flags = DS_DOMAIN_DIRECT_OUTBOUND; - domain->domain_type = DS_DOMAIN_TRUST_TYPE_UPLEVEL; + domain->domain_flags = NETR_TRUST_FLAG_OUTBOUND; + domain->domain_type = NETR_TRUST_TYPE_UPLEVEL; domain->internal = False; domain->online = True; @@ -1408,7 +1408,7 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) /* Can always contact a domain that is in out forest */ - if (tdc->trust_flags & DS_DOMAIN_IN_FOREST) { + if (tdc->trust_flags & NETR_TRUST_FLAG_IN_FOREST) { ret = true; goto done; } @@ -1420,7 +1420,7 @@ bool winbindd_can_contact_domain(struct winbindd_domain *domain) if (!IS_DC && domain->active_directory && - ((tdc->trust_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND)) + ((tdc->trust_flags & NETR_TRUST_FLAG_INBOUND) != NETR_TRUST_FLAG_INBOUND)) { DEBUG(10, ("winbindd_can_contact_domain: %s is an AD domain " "and we have no inbound trust.\n", domain->name)); -- cgit