Avoiding set_dc_type_and_flags() for trusted domains

Gerald (Jerry) Carter jerry at samba.org
Fri Mar 23 16:24:47 GMT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hey Guenther,

What do yo think about this patch (just actually testing it now).
It uses information from DsEnumerateDomainTrusts() to fill
in the dc_type and trust flags so we don't have to actually
contact the trusted DC.

The reason I'm doing this is to support one way outgoing
trusts between forests.  In this case we can't actually
contact the trusted DC as we have no credentials.
I'm just experimenting right now.  Thought you might be
interested.

btw...This can only be done when our primary domain is AD.




cheers, jerry
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.3 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGA/9PIR7qMdg1EfYRAiexAKCiAZAEGUkS1I8ZZFWrcaxv/DPDDQCgivUd
aEwli9RDcKEpubalWTljk3A=
=vQc2
-----END PGP SIGNATURE-----
-------------- next part --------------
Index: nsswitch/winbindd_cm.c
===================================================================
--- nsswitch/winbindd_cm.c	(revision 14148)
+++ nsswitch/winbindd_cm.c	(working copy)
@@ -1504,6 +1504,89 @@
 }
 
 /******************************************************************************
+ 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;	
+	
+	/* Our primary domain doesn't need to worry about trust flags */
+	if ( domain-> primary ) {		
+		return True;
+	}
+	
+	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;
+	}
+
+	/* our domain has to be initialized in order for this to work */
+	if ( !our_domain->initialized )
+		set_dc_type_and_flags( our_domain );
+	
+	/* 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(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;
+			
+			if ( domain->domain_type == DS_DOMAIN_TRUST_TYPE_UPLEVEL )
+				domain->active_directory = True;
+
+			domain->native_mode = (domain->domain_flags & DS_DOMAIN_NATIVE_MODE);
+
+			domain->initialized = 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 +1594,7 @@
  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 +1613,13 @@
 		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 +1636,7 @@
 	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 +1653,7 @@
 	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 +1663,7 @@
 	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 +1718,10 @@
 	}
 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 +1731,41 @@
 	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 ) ) {
+		DEBUG(1,("set_dc_type_and_flags: Set flags using trust "
+			 "information\n"));
+		return;		
+	}
+
+	/* Otherwise, fallback to contacting the domain dircetly */
+
+	set_dc_type_and_flags_connect( domain );
+
+	return;
+}
+
+
+
+/**********************************************************************
+***********************************************************************/
+
 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
 				   struct dcinfo **ppdc)
 {
Index: nsswitch/winbindd.h
===================================================================
--- nsswitch/winbindd.h	(revision 14148)
+++ nsswitch/winbindd.h	(working copy)
@@ -157,6 +157,8 @@
 	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 */
+	uint32 domain_flags;                   /* Domain flags from rpc_ds.h */	
+	uint32 domain_type;                    /* Domain type from rpc_ds.h */	
 	BOOL initialized;		       /* Did we already ask for the domain mode? */
 	BOOL native_mode;                      /* is this a win2k domain in native mode ? */
 	BOOL active_directory;                 /* is this a win2k active directory ? */
Index: include/rpc_ds.h
===================================================================
--- include/rpc_ds.h	(revision 14148)
+++ include/rpc_ds.h	(working copy)
@@ -30,7 +30,6 @@
 
 #define DS_ENUM_DOM_TRUSTS      0x28
 
-
 /* macros for RPC's */
 
 /* DSROLE_PRIMARY_DOMAIN_INFO_BASIC */
@@ -55,8 +54,6 @@
 #define DS_DOMAIN_FUCNTION_2003_MIXED	1
 #define DS_DOMAIN_FUNCTION_2003		2
 
-
-
 typedef struct
 {
 	uint16		machine_role;
@@ -85,7 +82,6 @@
 
 #define DsRolePrimaryDomainInfoBasic		1
 
-
 /* DS_Q_GETPRIMDOMINFO - DsGetPrimaryDomainInformation() request */
 typedef struct 
 {
@@ -143,6 +139,8 @@
 	
 } DS_DOMAIN_TRUSTS_CTR;
 
+/* Trust attributes */
+
 #define DS_DOMAIN_IN_FOREST           0x0001 	/* domains in the forest to which 
 						   we belong; even different domain trees */
 #define DS_DOMAIN_DIRECT_OUTBOUND     0x0002  	/* trusted domains */
@@ -152,6 +150,11 @@
 #define DS_DOMAIN_NATIVE_MODE         0x0010  	/* native mode AD servers */
 #define DS_DOMAIN_DIRECT_INBOUND      0x0020 	/* trusting domains */
 
+/* Trust types */
+
+#define DS_DOMAIN_TRUST_TYPE_DOWNLEVEL   0x00000001
+#define DS_DOMAIN_TRUST_TYPE_UPLEVEL     0x00000002
+
 /* DS_Q_ENUM_DOM_TRUSTS - DsEnumerateDomainTrusts() request */
 typedef struct 
 {


More information about the samba-technical mailing list