summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/winbindd_cm.c147
-rw-r--r--source3/nsswitch/winbindd_rpc.c2
-rw-r--r--source3/nsswitch/winbindd_util.c30
3 files changed, 170 insertions, 9 deletions
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 010d38fde9..fb290e2ba7 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -1504,6 +1504,106 @@ NTSTATUS init_dc_connection(struct winbindd_domain *domain)
}
/******************************************************************************
+ Set the trust flags (direction and forest location) for a domain
+******************************************************************************/
+
+static BOOL set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
+{
+ struct winbindd_domain *our_domain;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ struct ds_domain_trust *domains = NULL;
+ int count = 0;
+ int i;
+ uint32 flags = (DS_DOMAIN_IN_FOREST |
+ DS_DOMAIN_DIRECT_OUTBOUND |
+ DS_DOMAIN_DIRECT_INBOUND);
+ struct rpc_pipe_client *cli;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
+
+ /* Our primary domain doesn't need to worry about trust flags.
+ Force it to go through the network setup */
+ if ( domain->primary ) {
+ return False;
+ }
+
+ our_domain = find_our_domain();
+
+ if ( !connection_ok(our_domain) ) {
+ DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
+ return False;
+ }
+
+ /* This won't work unless our domain is AD */
+
+ if ( !our_domain->active_directory ) {
+ return False;
+ }
+
+ /* Use DsEnumerateDomainTrusts to get us the trust direction
+ and type */
+
+ result = cm_connect_netlogon(our_domain, &cli);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
+ "a connection to %s for PIPE_NETLOGON (%s)\n",
+ domain->name, nt_errstr(result)));
+ return False;
+ }
+
+ if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
+ DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
+ return False;
+ }
+
+ result = rpccli_ds_enum_domain_trusts(cli, mem_ctx,
+ cli->cli->desthost,
+ flags, &domains,
+ (unsigned int *)&count);
+
+ /* Now find the domain name and get the flags */
+
+ for ( i=0; i<count; i++ ) {
+ if ( strequal( domain->name, domains[i].netbios_domain ) ) {
+ domain->domain_flags = domains[i].flags;
+ domain->domain_type = domains[i].trust_type;
+ domain->domain_trust_attribs = domains[i].trust_attributes;
+
+ if ( domain->domain_type == DS_DOMAIN_TRUST_TYPE_UPLEVEL )
+ domain->active_directory = True;
+
+ /* This flag is only set if the domain is *our*
+ primary domain and the primary domain is in
+ native mode */
+
+ domain->native_mode = (domain->domain_flags & DS_DOMAIN_NATIVE_MODE);
+
+ DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
+ "native mode.\n", domain->name,
+ domain->native_mode ? "" : "NOT "));
+
+ DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
+ "running active directory.\n", domain->name,
+ domain->active_directory ? "" : "NOT "));
+
+
+ domain->initialized = True;
+
+ if ( !winbindd_can_contact_domain( domain) )
+ domain->internal = True;
+
+ break;
+ }
+ }
+
+ talloc_destroy( mem_ctx );
+
+ return domain->initialized;
+}
+
+/******************************************************************************
We can 'sense' certain things about the DC by it's replies to certain
questions.
@@ -1511,7 +1611,7 @@ NTSTATUS init_dc_connection(struct winbindd_domain *domain)
is native mode.
******************************************************************************/
-static void set_dc_type_and_flags( struct winbindd_domain *domain )
+static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
{
NTSTATUS result;
DS_DOMINFO_CTR ctr;
@@ -1530,13 +1630,13 @@ static void set_dc_type_and_flags( struct winbindd_domain *domain )
return;
}
- DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
+ DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
&result);
if (cli == NULL) {
- DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
+ DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
"PI_LSARPC_DS on domain %s: (%s)\n",
domain->name, nt_errstr(result)));
@@ -1553,7 +1653,7 @@ static void set_dc_type_and_flags( struct winbindd_domain *domain )
cli_rpc_pipe_close(cli);
if (!NT_STATUS_IS_OK(result)) {
- DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
+ DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
"on domain %s failed: (%s)\n",
domain->name, nt_errstr(result)));
return;
@@ -1570,7 +1670,7 @@ no_lsarpc_ds:
cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
if (cli == NULL) {
- DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
+ DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
"PI_LSARPC on domain %s: (%s)\n",
domain->name, nt_errstr(result)));
cli_rpc_pipe_close(cli);
@@ -1580,7 +1680,7 @@ no_lsarpc_ds:
mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
domain->name);
if (!mem_ctx) {
- DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
+ DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
cli_rpc_pipe_close(cli);
return;
}
@@ -1635,10 +1735,10 @@ no_lsarpc_ds:
}
done:
- DEBUG(5, ("set_dc_type_and_flags: domain %s is %sin native mode.\n",
+ DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
domain->name, domain->native_mode ? "" : "NOT "));
- DEBUG(5,("set_dc_type_and_flags: domain %s is %srunning active directory.\n",
+ DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
domain->name, domain->active_directory ? "" : "NOT "));
cli_rpc_pipe_close(cli);
@@ -1648,6 +1748,37 @@ done:
domain->initialized = True;
}
+/**********************************************************************
+ Set the domain_flags (trust attributes, domain operating modes, etc...
+***********************************************************************/
+
+static void set_dc_type_and_flags( struct winbindd_domain *domain )
+{
+ /* we always have to contact our primary domain */
+
+ if ( domain->primary ) {
+ DEBUG(10,("set_dc_type_and_flags: setting up flags for "
+ "primary domain\n"));
+ set_dc_type_and_flags_connect( domain );
+ return;
+ }
+
+ /* Use our DC to get the information if possible */
+
+ if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
+ /* Otherwise, fallback to contacting the
+ domain directly */
+ set_dc_type_and_flags_connect( domain );
+ }
+
+ return;
+}
+
+
+
+/**********************************************************************
+***********************************************************************/
+
static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
struct dcinfo **ppdc)
{
diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c
index f408e1e15e..a66b05b791 100644
--- a/source3/nsswitch/winbindd_rpc.c
+++ b/source3/nsswitch/winbindd_rpc.c
@@ -828,7 +828,7 @@ static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
return NT_STATUS_NO_MEMORY;
#ifdef HAVE_LDAP
- if ( domain->native_mode )
+ if ( domain->active_directory )
{
int res;
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 56de808c2d..d58fffd0db 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -1233,3 +1233,33 @@ void ws_name_return( char *name, char replace )
return;
}
+
+/*********************************************************************
+ ********************************************************************/
+
+BOOL winbindd_can_contact_domain( struct winbindd_domain *domain )
+{
+ /* We can contact the domain if it is our primary domain */
+
+ if ( domain->primary )
+ return True;
+
+ /* Can always contact a domain that is in out forest */
+
+ 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 */
+
+ if ( domain->active_directory &&
+ ((domain->domain_flags&DS_DOMAIN_DIRECT_INBOUND) != DS_DOMAIN_DIRECT_INBOUND) )
+ {
+ return False;
+ }
+
+ /* Assume everything else is ok (probably not true but what
+ can you do?) */
+
+ return True;
+}