Commit 9dbf2e24 authored by Gerald Carter's avatar Gerald Carter Committed by Gerald (Jerry) Carter
Browse files

r991: Allow winbindd to use the domain trust account password

for setting up an schannel connection.  This solves the problem
of a Samba DC running winbind, trusting a native mode AD domain,
and needing to enumerate AD users via wbinfo -u.
(This used to be commit e9f109d1b38e0b0adec9b7e9a907f90a79d297ea)
parent 4e1b26db
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1425,8 +1425,10 @@ BOOL is_trusted_domain(const char* dom_name)

	/* if we are a DC, then check for a direct trust relationships */

	if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
	if ( IS_DC ) {
		become_root();
		DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",
			dom_name ));
		ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);
		unbecome_root();
		SAFE_FREE(pass);
+2 −1
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ enum RPC_PKT_TYPE
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
 
#define NETLOGON_NEG_SCHANNEL    		0x40000000
#define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT	0x2010b000

enum netsec_direction
{
+35 −7
Original line number Diff line number Diff line
@@ -68,6 +68,11 @@
#define SAM_DATABASE_BUILTIN   0x01 /* BUILTIN users and groups */
#define SAM_DATABASE_PRIVS     0x02 /* Privileges */

#define NETLOGON_CONTROL_REDISCOVER		0x5
#define NETLOGON_CONTROL_TC_QUERY		0x6
#define NETLOGON_CONTROL_TRANSPORT_NOTIFY	0x7
#define NETLOGON_CONTROL_SET_DBFLAG		0xfffe

#if 0
/* I think this is correct - it's what gets parsed on the wire. JRA. */
/* NET_USER_INFO_2 */
@@ -204,7 +209,7 @@ typedef struct netlogon_2_info
	uint32  flags;            /* 0x0 - undocumented */
	uint32  pdc_status;       /* 0x0 - undocumented */
	uint32  ptr_trusted_dc_name; /* pointer to trusted domain controller name */
	uint32  tc_status;           /* 0x051f - ERROR_NO_LOGON_SERVERS */
	uint32  tc_status;           
	UNISTR2 uni_trusted_dc_name; /* unicode string - trusted dc name */

} NETLOGON_INFO_2;
@@ -255,6 +260,26 @@ typedef struct net_r_logon_ctrl_info
	NTSTATUS status;
} NET_R_LOGON_CTRL;


typedef struct ctrl_data_info_5
{
	uint32 		function_code;
	
	uint32		ptr_domain;
	UNISTR2		domain;
	
} CTRL_DATA_INFO_5;

typedef struct ctrl_data_info_6
{
	uint32 		function_code;
	
	uint32		ptr_domain;
	UNISTR2		domain;
	
} CTRL_DATA_INFO_6;


/********************************************************
 Logon Control2 Query

@@ -269,9 +294,12 @@ typedef struct net_q_logon_ctrl2_info
	uint32       	ptr;             /* undocumented buffer pointer */
	UNISTR2      	uni_server_name; /* server name, starting with two '\'s */
	
	uint32       function_code; /* 0x1 */
	uint32       query_level;   /* 0x1, 0x3 */
	uint32       switch_value;  /* 0x1 */
	uint32       	function_code; 
	uint32       	query_level;   
	union {
		CTRL_DATA_INFO_5 info5;
		CTRL_DATA_INFO_6 info6;;
	} info;
	
} NET_Q_LOGON_CTRL2;

+6 −0
Original line number Diff line number Diff line
@@ -363,6 +363,12 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
	if ( NT_STATUS_IS_OK(status) )
		goto done;	

	/* important! make sure that we know if this is a native 
	   mode domain or not */

	if ( !domain->initialized )
		set_dc_type_and_flags( domain );

	status = domain->backend->sequence_number(domain, &domain->sequence_number);

	if (!NT_STATUS_IS_OK(status)) {
+35 −11
Original line number Diff line number Diff line
@@ -117,21 +117,40 @@ static void cm_get_ipc_userpass(char **username, char **domain, char **password)
/*
  setup for schannel on any pipes opened on this connection
*/
static NTSTATUS setup_schannel(struct cli_state *cli)
static NTSTATUS setup_schannel( struct cli_state *cli, const char *domain )
{
	NTSTATUS ret;
	uchar trust_password[16];
	uint32 sec_channel_type;
	DOM_SID sid;
	time_t lct;

	/* use the domain trust password if we're on a DC 
	   and this is not our domain */
	
	if ( IS_DC && !strequal(domain, lp_workgroup()) ) {
		char *pass = NULL;
		
		if ( !secrets_fetch_trusted_domain_password( domain, 
			&pass, &sid, &lct) )
		{
			return NT_STATUS_UNSUCCESSFUL;
		}	

		sec_channel_type = SEC_CHAN_DOMAIN;
		E_md4hash(pass, trust_password);
		SAFE_FREE( pass );
		
	} else {
		if (!secrets_fetch_trust_account_password(lp_workgroup(),
						  trust_password,
						  NULL, &sec_channel_type)) {
			trust_password, NULL, &sec_channel_type)) 
		{
			return NT_STATUS_UNSUCCESSFUL;
		}
	}

	ret = cli_nt_setup_netsec(cli, sec_channel_type, 
				  AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN, 
				  trust_password);
		AUTH_PIPE_NETSEC | AUTH_PIPE_SIGN, trust_password);

	return ret;
}
@@ -217,6 +236,7 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
	fstrcpy(new_conn->pipe_name, get_pipe_name_from_index(pipe_index));

	/* grab stored passwords */
	
	machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
	
	if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(), lp_realm()) == -1) {
@@ -335,9 +355,13 @@ static NTSTATUS cm_open_connection(const struct winbindd_domain *domain, const i
	/* try and use schannel if possible, but continue anyway if it
	   failed. This allows existing setups to continue working,
	   while solving the win2003 '100 user' limit for systems that
	   are joined properly */
	if (NT_STATUS_IS_OK(result) && (domain->primary)) {
		NTSTATUS status = setup_schannel(new_conn->cli);
	   are joined properly.
	
	   Only do this for our own domain or perhaps a trusted domain
	   if we are on a Samba DC */

	if (NT_STATUS_IS_OK(result) && (domain->primary || IS_DC) ) {
		NTSTATUS status = setup_schannel( new_conn->cli, domain->name );
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(3,("schannel refused - continuing without schannel (%s)\n", 
				 nt_errstr(status)));
Loading