summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_ads.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch/winbindd_ads.c')
-rw-r--r--source3/nsswitch/winbindd_ads.c82
1 files changed, 77 insertions, 5 deletions
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 355a093855..111736244a 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -1020,8 +1020,10 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
struct ds_domain_trust *domains = NULL;
int count = 0;
int i;
- uint32 flags = DS_DOMAIN_IN_FOREST | DS_DOMAIN_DIRECT_OUTBOUND;
+ uint32 flags;
struct rpc_pipe_client *cli;
+ uint32 fr_flags = (DS_DOMAIN_IN_FOREST | DS_DOMAIN_TREE_ROOT);
+ int ret_count;
DEBUG(3,("ads: trusted_domains\n"));
@@ -1030,6 +1032,20 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
*names = NULL;
*dom_sids = NULL;
+ /* If this is our primary domain or a root in our forest,
+ query for all trusts. If not, then just look for domain
+ trusts in the target forest */
+
+ if ( domain->primary ||
+ ((domain->domain_flags&fr_flags) == fr_flags) )
+ {
+ flags = DS_DOMAIN_DIRECT_OUTBOUND |
+ DS_DOMAIN_DIRECT_INBOUND |
+ DS_DOMAIN_IN_FOREST;
+ } else {
+ flags = DS_DOMAIN_IN_FOREST;
+ }
+
result = cm_connect_netlogon(domain, &cli);
if (!NT_STATUS_IS_OK(result)) {
@@ -1067,14 +1083,70 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
/* Copy across names and sids */
+
+ ret_count = 0;
for (i = 0; i < count; i++) {
- (*names)[i] = domains[i].netbios_domain;
- (*alt_names)[i] = domains[i].dns_domain;
+ struct winbindd_domain d;
+
+ /* drop external trusts if this is not our primary
+ domain. This means that the returned number of
+ domains may be less that the ones actually trusted
+ by the DC. */
+
+ if ( (domains[i].trust_attributes == DS_DOMAIN_TRUST_ATTRIB_QUARANTINED_DOMAIN) &&
+ !domain->primary )
+ {
+ DEBUG(10,("trusted_domains: Skipping external trusted domain "
+ "%s because it is outside of our primary domain\n",
+ domains[i].netbios_domain));
+ continue;
+ }
+
+ (*names)[ret_count] = domains[i].netbios_domain;
+ (*alt_names)[ret_count] = domains[i].dns_domain;
+ sid_copy(&(*dom_sids)[ret_count], &domains[i].sid);
+
+ /* add to the trusted domain cache */
+
+ fstrcpy( d.name, domains[i].netbios_domain );
+ fstrcpy( d.alt_name, domains[i].dns_domain );
+ sid_copy( &d.sid, &domains[i].sid );
+
+ /* This gets a little tricky. If we are
+ following a transitive forest trust, then
+ innerit the flags, type, and attrins from
+ the domain we queried to make sure we don't
+ record the view of the trust from the wrong
+ side. Always view it from the side of our
+ primary domain. --jerry */
+ if ( domain->primary ||
+ ((domain->domain_flags&fr_flags) == fr_flags) )
+ {
+ DEBUG(10,("trusted_domains(ads): Storing trust "
+ "flags for domain %s\n", d.alt_name));
+
+ /* Look this up in cache to make sure
+ we have the current trust flags and
+ attributes */
+
+ d.domain_flags = domains[i].flags;
+ d.domain_type = domains[i].trust_type;
+ d.domain_trust_attribs = domains[i].trust_attributes;
+ } else {
+ DEBUG(10,("trusted_domains(ads): Inheriting trust "
+ "flags for domain %s\n", d.alt_name));
+ d.domain_flags = domain->domain_flags;
+ d.domain_type = domain->domain_type;
+ d.domain_trust_attribs = domain->domain_trust_attribs;
+ }
+
+ wcache_tdc_add_domain( &d );
+
+ ret_count++;
- sid_copy(&(*dom_sids)[i], &domains[i].sid);
}
- *num_domains = count;
+ *num_domains = ret_count;
}
return result;