[PATCH] Use ADS for all compatible domains

Andrew Bartlett abartlet at samba.org
Mon Jan 5 12:44:21 GMT 2004


This patch ensures that for all ADS domains (using the same test that
MS uses in their clients apparently) we use the ADS methods to contact
our trusted domains.  Previously, we would only handle caes where the
domain was in 'native mode'.

This is for trusted domains only - we always follow our smb.conf for
the primary domain.

I need help testing this, particularly on sites with Samba, NT4 and
mixed-mode DCs in trust relationships.

Andrew Bartlett
-------------- next part --------------
? config.abartlet
? passdb.xml
? auth/auth_util.idmap-conflict.c
? bin/stNDYv74
? include/smb_ldap.h
? modules/developer.c
? modules/vfs_fake_perms-old.c
? passdb/pdb_ldap.c2
Index: nsswitch/winbindd.h
===================================================================
RCS file: /home/cvs/samba/source/nsswitch/winbindd.h,v
retrieving revision 1.33.2.17
diff -u -r1.33.2.17 winbindd.h
--- nsswitch/winbindd.h	5 Jan 2004 02:04:36 -0000	1.33.2.17
+++ nsswitch/winbindd.h	5 Jan 2004 12:37:21 -0000
@@ -95,7 +95,8 @@
 	fstring alt_name;                      /* alt Domain name (if any) */
 	DOM_SID sid;                           /* SID for this domain */
 	BOOL native_mode;                      /* is this a win2k domain in native mode ? */
-	BOOL primary;                           /* is this our primary domain ? */
+	BOOL active_directory;                 /* is this a win2k active directory ? */
+	BOOL primary;                          /* is this our primary domain ? */
 
 	/* Lookup methods for this domain (LDAP or RPC) */
 	struct winbindd_methods *methods;
Index: nsswitch/winbindd_cache.c
===================================================================
RCS file: /home/cvs/samba/source/nsswitch/winbindd_cache.c,v
retrieving revision 1.35.2.21
diff -u -r1.35.2.21 winbindd_cache.c
--- nsswitch/winbindd_cache.c	5 Jan 2004 02:16:51 -0000	1.35.2.21
+++ nsswitch/winbindd_cache.c	5 Jan 2004 12:37:23 -0000
@@ -107,12 +107,14 @@
 		case SEC_ADS: {
 			extern struct winbindd_methods ads_methods;
 			/* always obey the lp_security parameter for our domain */
-			if ( strequal(lp_realm(), domain->alt_name) || strequal(lp_workgroup(), domain->name) ) {
+			if (domain->primary) {
 				domain->backend = &ads_methods;
 				break;
 			}
 
-			if ( domain->native_mode ) {
+			/* if it have either of the indications of ADS, 
+			   use ads_methods */
+			if ( domain->active_directory || domain->native_mode ) {
 				domain->backend = &ads_methods;
 				break;
 			}
Index: nsswitch/winbindd_cm.c
===================================================================
RCS file: /home/cvs/samba/source/nsswitch/winbindd_cm.c,v
retrieving revision 1.31.2.46
diff -u -r1.31.2.46 winbindd_cm.c
--- nsswitch/winbindd_cm.c	5 Jan 2004 04:10:27 -0000	1.31.2.46
+++ nsswitch/winbindd_cm.c	5 Jan 2004 12:37:25 -0000
@@ -405,23 +405,30 @@
 }
 
 /**********************************************************************************
+ We can 'sense' certain things about the DC by it's replies to certain questions.
+
+ This tells us if this particular remote server is Active Directory, and if it is
+ native mode.
 **********************************************************************************/
 
-BOOL cm_check_for_native_mode_win2k( struct winbindd_domain *domain )
+void set_dc_type_and_flags( struct winbindd_domain *domain )
 {
 	NTSTATUS 		result;
 	struct winbindd_cm_conn	conn;
 	DS_DOMINFO_CTR		ctr;
 	BOOL			ret = False;
+	TALLOC_CTX              *mem_ctx;
 	
 	ZERO_STRUCT( conn );
 	ZERO_STRUCT( ctr );
 	
+	domain->native_mode = True;
+	domain->active_directory = False;
 	
 	if ( !NT_STATUS_IS_OK(result = cm_open_connection(domain, PI_LSARPC_DS, &conn)) ) {
-		DEBUG(5, ("cm_check_for_native_mode_win2k: Could not open a connection to %s for PIPE_LSARPC (%s)\n", 
+		DEBUG(5, ("set_dc_type_and_flags: Could not open a connection to %s for PIPE_LSARPC (%s)\n", 
 			  domain->name, nt_errstr(result)));
-		return False;
+		return;
 	}
 	
 	if ( conn.cli ) {
@@ -434,17 +441,82 @@
 				
 	if ( (ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) 
 			&& !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
-		ret = True;
+		domain->native_mode = True;
 
-done:
+	/* Cheat - shut down the DS pipe, and open LSA */
+
+	cli_nt_session_close(conn.cli);
+
+	if ( cli_nt_session_open (conn.cli, PI_LSARPC) ) {
+		char *domain_name = NULL;
+		char *dns_name = NULL;
+		DOM_SID *dom_sid = NULL;
+
+		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"));
+			return;
+		}
+
+		result = cli_lsa_open_policy2(conn.cli, mem_ctx, True, 
+					      SEC_RIGHTS_MAXIMUM_ALLOWED,
+					      &conn.pol);
+		
+		if (NT_STATUS_IS_OK(result)) {
+			/* This particular query is exactly what Win2k clients use 
+			   to determine that the DC is active directory */
+			result = cli_lsa_query_info_policy2(conn.cli, mem_ctx, 
+							    &conn.pol,
+							    12, &domain_name,
+							    &dns_name, NULL,
+							    NULL, &dom_sid);
+		}
+
+		if (NT_STATUS_IS_OK(result)) {
+			if (domain_name)
+				fstrcpy(domain->name, domain_name);
+			
+			if (dns_name)
+				fstrcpy(domain->alt_name, dns_name);
+
+			if (dom_sid) 
+				sid_copy(&domain->sid, dom_sid);
 
+			domain->active_directory = True;
+		} else {
+			
+			result = cli_lsa_open_policy(conn.cli, mem_ctx, True, 
+						     SEC_RIGHTS_MAXIMUM_ALLOWED,
+						     &conn.pol);
+			
+			if (!NT_STATUS_IS_OK(result))
+				goto done;
+			
+			result = cli_lsa_query_info_policy(conn.cli, mem_ctx, 
+							   &conn.pol, 5, &domain_name, 
+							   &dom_sid);
+			
+			if (NT_STATUS_IS_OK(result)) {
+				if (domain_name)
+					fstrcpy(domain->name, domain_name);
+				
+				if (dom_sid) 
+					sid_copy(&domain->sid, dom_sid);
+			}
+		}
+	}
+	
+done:
+	
 	/* close the connection;  no other cals use this pipe and it is called only
 	   on reestablishing the domain list   --jerry */
-
+	
 	if ( conn.cli )
 		cli_shutdown( conn.cli );
 	
-	return ret;
+	talloc_destroy(mem_ctx);
+	
+	return;
 }
 
 
Index: nsswitch/winbindd_util.c
===================================================================
RCS file: /home/cvs/samba/source/nsswitch/winbindd_util.c,v
retrieving revision 1.73.2.41
diff -u -r1.73.2.41 winbindd_util.c
--- nsswitch/winbindd_util.c	5 Jan 2004 04:10:28 -0000	1.73.2.41
+++ nsswitch/winbindd_util.c	5 Jan 2004 12:37:31 -0000
@@ -134,9 +134,9 @@
 		sid_copy(&domain->sid, sid);
 	}
 	
-	/* see if this is a native mode win2k domain */
+	/* set flags about native_mode, active_directory */
 	   
-	domain->native_mode = cm_check_for_native_mode_win2k( domain );
+	set_dc_type_and_flags( domain );
 	
 	DEBUG(3,("add_trusted_domain: %s is a %s mode domain\n", domain->name,
 		domain->native_mode ? "native" : "mixed (or NT4)" ));
@@ -222,7 +222,7 @@
 		for(i = 0; i < num_domains; i++) {
 			DEBUG(10,("Found domain %s\n", names[i]));
 			add_trusted_domain(names[i], alt_names?alt_names[i]:NULL,
-				domain->methods, &dom_sids[i]);
+					   domain->methods, &dom_sids[i]);
 					   
 			/* if the SID was empty, we better set it now */
 			
Index: rpc_client/cli_lsarpc.c
===================================================================
RCS file: /home/cvs/samba/source/rpc_client/cli_lsarpc.c,v
retrieving revision 1.68.2.9
diff -u -r1.68.2.9 cli_lsarpc.c
--- rpc_client/cli_lsarpc.c	5 Jan 2004 02:04:37 -0000	1.68.2.9
+++ rpc_client/cli_lsarpc.c	5 Jan 2004 12:37:37 -0000
@@ -443,7 +443,7 @@
 
 NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx,
                                    POLICY_HND *pol, uint16 info_class, 
-                                   fstring domain_name, DOM_SID *domain_sid)
+                                   char **domain_name, DOM_SID **domain_sid)
 {
 	prs_struct qbuf, rbuf;
 	LSA_Q_QUERY_INFO q;
@@ -481,39 +481,40 @@
 
 	/* Return output parameters */
 
-	ZERO_STRUCTP(domain_sid);
-	domain_name[0] = '\0';
-
 	switch (info_class) {
 
 	case 3:
-		if (r.dom.id3.buffer_dom_name != 0) {
-			unistr2_to_ascii(domain_name,
-					 &r.dom.id3.
-					 uni_domain_name,
-					 sizeof (fstring) - 1);
+		if (domain_name && (r.dom.id3.buffer_dom_name != 0)) {
+			*domain_name = unistr2_tdup(mem_ctx, 
+						   &r.dom.id3.
+						   uni_domain_name);
 		}
 
-		if (r.dom.id3.buffer_dom_sid != 0) {
-			*domain_sid = r.dom.id3.dom_sid.sid;
+		if (domain_sid && (r.dom.id3.buffer_dom_sid != 0)) {
+			*domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
+			if (*domain_sid) {
+				sid_copy(*domain_sid, &r.dom.id3.dom_sid.sid);
+			}
 		}
 
 		break;
 
 	case 5:
 		
-		if (r.dom.id5.buffer_dom_name != 0) {
-			unistr2_to_ascii(domain_name, &r.dom.id5.
-					 uni_domain_name,
-					 sizeof (fstring) - 1);
+		if (domain_name && (r.dom.id5.buffer_dom_name != 0)) {
+			*domain_name = unistr2_tdup(mem_ctx, 
+						   &r.dom.id5.
+						   uni_domain_name);
 		}
 			
-		if (r.dom.id5.buffer_dom_sid != 0) {
-			*domain_sid = r.dom.id5.dom_sid.sid;
+		if (domain_sid && (r.dom.id5.buffer_dom_sid != 0)) {
+			*domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
+			if (*domain_sid) {
+				sid_copy(*domain_sid, &r.dom.id5.dom_sid.sid);
+			}
 		}
-
 		break;
-		
+			
 	default:
 		DEBUG(3, ("unknown info class %d\n", info_class));
 		break;		      
@@ -536,9 +537,9 @@
 
 NTSTATUS cli_lsa_query_info_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 				    POLICY_HND *pol, uint16 info_class, 
-				    fstring domain_name, fstring dns_name,
-				    fstring forest_name, GUID *domain_guid,
-				    DOM_SID *domain_sid)
+				    char **domain_name, char **dns_name,
+				    char **forest_name, GUID **domain_guid,
+				    DOM_SID **domain_sid)
 {
 	prs_struct qbuf, rbuf;
 	LSA_Q_QUERY_INFO2 q;
@@ -579,30 +580,37 @@
 
 	/* Return output parameters */
 
-	ZERO_STRUCTP(domain_sid);
 	ZERO_STRUCTP(domain_guid);
-	domain_name[0] = '\0';
 
-	if (r.info.dns_dom_info.hdr_nb_dom_name.buffer) {
-		unistr2_to_ascii(domain_name,
-				 &r.info.dns_dom_info.uni_nb_dom_name,
-				 sizeof(fstring) - 1);
-	}
-	if (r.info.dns_dom_info.hdr_dns_dom_name.buffer) {
-		unistr2_to_ascii(dns_name,
-				 &r.info.dns_dom_info.uni_dns_dom_name,
-				 sizeof(fstring) - 1);
-	}
-	if (r.info.dns_dom_info.hdr_forest_name.buffer) {
-		unistr2_to_ascii(forest_name,
-				 &r.info.dns_dom_info.uni_forest_name,
-				 sizeof(fstring) - 1);
+	if (domain_name && r.info.dns_dom_info.hdr_nb_dom_name.buffer) {
+		*domain_name = unistr2_tdup(mem_ctx, 
+					    &r.info.dns_dom_info
+					    .uni_nb_dom_name);
+	}
+	if (dns_name && r.info.dns_dom_info.hdr_dns_dom_name.buffer) {
+		*dns_name = unistr2_tdup(mem_ctx, 
+					 &r.info.dns_dom_info
+					 .uni_dns_dom_name);
+	}
+	if (forest_name && r.info.dns_dom_info.hdr_forest_name.buffer) {
+		*forest_name = unistr2_tdup(mem_ctx, 
+					    &r.info.dns_dom_info
+					    .uni_forest_name);
 	}
 	
-	memcpy(domain_guid, &r.info.dns_dom_info.dom_guid, sizeof(GUID));
+	if (domain_guid) {
+		*domain_guid = talloc(mem_ctx, sizeof(**domain_guid));
+		memcpy(*domain_guid, 
+		       &r.info.dns_dom_info.dom_guid, 
+		       sizeof(GUID));
+	}
 
-	if (r.info.dns_dom_info.ptr_dom_sid != 0) {
-		*domain_sid = r.info.dns_dom_info.dom_sid.sid;
+	if (domain_sid && r.info.dns_dom_info.ptr_dom_sid != 0) {
+		*domain_sid = talloc(mem_ctx, sizeof(**domain_sid));
+		if (*domain_sid) {
+			sid_copy(*domain_sid, 
+				 &r.info.dns_dom_info.dom_sid.sid);
+		}
 	}
 	
  done:
Index: rpcclient/cmd_lsarpc.c
===================================================================
RCS file: /home/cvs/samba/source/rpcclient/cmd_lsarpc.c,v
retrieving revision 1.58.2.14
diff -u -r1.58.2.14 cmd_lsarpc.c
--- rpcclient/cmd_lsarpc.c	18 Mar 2003 06:30:30 -0000	1.58.2.14
+++ rpcclient/cmd_lsarpc.c	5 Jan 2004 12:37:38 -0000
@@ -68,9 +68,13 @@
 {
 	POLICY_HND pol;
 	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-	DOM_SID dom_sid;
-	GUID dom_guid;
-	fstring sid_str, domain_name="", dns_name="", forest_name="";
+	DOM_SID *dom_sid;
+	GUID *dom_guid;
+	fstring sid_str;
+	char *domain_name = NULL;
+	char *dns_name = NULL;
+	char *forest_name = NULL;
+
 	uint32 info_class = 3;
 
 	if (argc > 2) {
@@ -91,8 +95,8 @@
 		if (!NT_STATUS_IS_OK(result))
 			goto done;
 		result = cli_lsa_query_info_policy2(cli, mem_ctx, &pol,
-						    info_class, domain_name,
-						    dns_name, forest_name,
+						    info_class, &domain_name,
+						    &dns_name, &forest_name,
 						    &dom_guid, &dom_sid);
 		break;
 	default:
@@ -103,23 +107,23 @@
 		if (!NT_STATUS_IS_OK(result))
 			goto done;
 		result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, 
-						   info_class, domain_name, 
+						   info_class, &domain_name, 
 						   &dom_sid);
 	}
 
 	if (!NT_STATUS_IS_OK(result))
 		goto done;
+	
+	sid_to_string(sid_str, dom_sid);
 
-	sid_to_string(sid_str, &dom_sid);
-
-	if (domain_name[0])
+	if (domain_name)
 		printf("domain %s has sid %s\n", domain_name, sid_str);
 	else
 		printf("could not query info for level %d\n", info_class);
 
-	if (dns_name[0])
+	if (dns_name)
 		printf("domain dns name is %s\n", dns_name);
-	if (forest_name[0])
+	if (forest_name)
 		printf("forest name is %s\n", forest_name);
 
 	if (info_class == 12) {
Index: utils/net_rpc.c
===================================================================
RCS file: /home/cvs/samba/source/utils/net_rpc.c,v
retrieving revision 1.14.2.42
diff -u -r1.14.2.42 net_rpc.c
--- utils/net_rpc.c	2 Jan 2004 05:32:07 -0000	1.14.2.42
+++ utils/net_rpc.c	5 Jan 2004 12:37:41 -0000
@@ -48,27 +48,14 @@
  * @return The Domain SID of the remote machine.
  **/
 
-static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli)
+static DOM_SID *net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx)
 {
 	DOM_SID *domain_sid;
 	POLICY_HND pol;
 	NTSTATUS result = NT_STATUS_OK;
 	uint32 info_class = 5;
-	fstring domain_name;
-	TALLOC_CTX *mem_ctx;
+        char *domain_name;
 	
-	if (!(domain_sid = malloc(sizeof(DOM_SID)))){
-		DEBUG(0,("net_get_remote_domain_sid: malloc returned NULL!\n"));
-		goto error;
-	}
-	    
-	if (!(mem_ctx=talloc_init("net_get_remote_domain_sid")))
-	{
-		DEBUG(0,("net_get_remote_domain_sid: talloc_init returned NULL!\n"));
-		goto error;
-	}
-
-
 	if (!cli_nt_session_open (cli, PI_LSARPC)) {
 		fprintf(stderr, "could not initialise lsa pipe\n");
 		goto error;
@@ -82,7 +69,7 @@
 	}
 
 	result = cli_lsa_query_info_policy(cli, mem_ctx, &pol, info_class, 
-					   domain_name, domain_sid);
+					   &domain_name, &domain_sid);
 	if (!NT_STATUS_IS_OK(result)) {
  error:
 		fprintf(stderr, "could not obtain sid for domain %s\n", cli->domain);
@@ -96,7 +83,6 @@
 
 	cli_lsa_close(cli, mem_ctx, &pol);
 	cli_nt_session_close(cli);
-	talloc_destroy(mem_ctx);
 
 	return domain_sid;
 }
@@ -132,7 +118,7 @@
 		return -1;
 	}
 
-	domain_sid = net_get_remote_domain_sid(cli);
+	domain_sid = net_get_remote_domain_sid(cli, mem_ctx);
 
 	/* Create mem_ctx */
 	
@@ -1928,10 +1914,11 @@
 	POLICY_HND connect_hnd;
 	TALLOC_CTX *mem_ctx;
 	NTSTATUS nt_status;
-	DOM_SID domain_sid;
+	DOM_SID *domain_sid;
 	WKS_INFO_100 wks_info;
 	
 	char* domain_name;
+	char* domain_name_pol;
 	char* acct_name;
 	fstring pdc_name;
 
@@ -2052,7 +2039,7 @@
 	/* Querying info level 5 */
 	
 	nt_status = cli_lsa_query_info_policy(cli, mem_ctx, &connect_hnd,
-	                                      5 /* info level */, domain_name,
+	                                      5 /* info level */, &domain_name_pol,
 	                                      &domain_sid);
 	if (NT_STATUS_IS_ERR(nt_status)) {
 		DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
@@ -2072,7 +2059,7 @@
 
 	if (!secrets_store_trusted_domain_password(domain_name, wks_info.uni_lan_grp.buffer,
 						   wks_info.uni_lan_grp.uni_str_len, opt_password,
-						   domain_sid)) {
+						   *domain_sid)) {
 		DEBUG(0, ("Storing password for trusted domain failed.\n"));
 		return -1;
 	}
@@ -2163,7 +2150,7 @@
 	struct cli_state *cli, *remote_cli;
 	NTSTATUS nt_status;
 	const char *domain_name = NULL;
-	DOM_SID queried_dom_sid;
+	DOM_SID *queried_dom_sid;
 	fstring ascii_sid, padding;
 	int ascii_dom_name_len;
 	POLICY_HND connect_hnd;
@@ -2173,7 +2160,8 @@
 	int i, pad_len, col_len = 20;
 	DOM_SID *domain_sids;
 	char **trusted_dom_names;
-	fstring pdc_name, dummy;
+	fstring pdc_name;
+	char *dummy;
 	
 	/* trusting domains listing variables */
 	POLICY_HND domain_hnd;
@@ -2222,7 +2210,7 @@
 	/* query info level 5 to obtain sid of a domain being queried */
 	nt_status = cli_lsa_query_info_policy(
 		cli, mem_ctx, &connect_hnd, 5 /* info level */, 
-		dummy, &queried_dom_sid);
+		&dummy, &queried_dom_sid);
 
 	if (NT_STATUS_IS_ERR(nt_status)) {
 		DEBUG(0, ("LSA Query Info failed. Returned error was %s\n",
@@ -2304,8 +2292,8 @@
 	/* SamrOpenDomain - we have to open domain policy handle in order to be
 	   able to enumerate accounts*/
 	nt_status = cli_samr_open_domain(cli, mem_ctx, &connect_hnd,
-									 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
-									 &queried_dom_sid, &domain_hnd);									 
+					 SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
+					 queried_dom_sid, &domain_hnd);									 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0, ("Couldn't open domain object. Error was %s\n",
 			nt_errstr(nt_status)));


More information about the samba-technical mailing list