mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
[merge from APP_HEAD]
90% fix for CR 1076. The password server parameter will no take things
like
password server = DC1 *
which means to contact DC1 first and the go to auto lookup if it
fails.
jerry
(This used to be commit 016ef8b36b
)
This commit is contained in:
parent
f230981e2c
commit
3ab6fcc5c6
@ -275,6 +275,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||
NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS;
|
||||
time_t time_now = time(NULL);
|
||||
BOOL use_pdc_only = False;
|
||||
BOOL list_ordered;
|
||||
|
||||
/*
|
||||
* If the time the machine password has changed
|
||||
@ -301,7 +302,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||
count = 1;
|
||||
|
||||
} else {
|
||||
if (!get_dc_list(domain, &ip_list, &count))
|
||||
if (!get_dc_list(domain, &ip_list, &count, &list_ordered))
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
@ -310,7 +311,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||
* network address as any of our interfaces.
|
||||
*/
|
||||
for(i = 0; i < count; i++) {
|
||||
if(!is_local_net(ip_list[i]))
|
||||
if( !list_ordered && !is_local_net(ip_list[i]) )
|
||||
continue;
|
||||
|
||||
if(NT_STATUS_IS_OK(nt_status =
|
||||
|
@ -186,6 +186,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads)
|
||||
int count;
|
||||
int i;
|
||||
const char *workgroup = ads->server.workgroup;
|
||||
BOOL list_ordered;
|
||||
|
||||
if (!workgroup) {
|
||||
workgroup = lp_workgroup();
|
||||
@ -202,7 +203,7 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads)
|
||||
}
|
||||
|
||||
/* now any DC, including backups */
|
||||
if (get_dc_list(workgroup, &ip_list, &count)) {
|
||||
if (get_dc_list(workgroup, &ip_list, &count, &list_ordered)) {
|
||||
for (i=0;i<count;i++) {
|
||||
DEBUG(6,("ads_try_netbios: trying server '%s'\n",
|
||||
inet_ntoa(ip_list[i])));
|
||||
|
@ -1235,19 +1235,24 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
|
||||
a domain.
|
||||
*********************************************************/
|
||||
|
||||
BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count)
|
||||
BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
|
||||
{
|
||||
/*
|
||||
* If it's our domain then
|
||||
* use the 'password server' parameter.
|
||||
*/
|
||||
|
||||
*ordered = False;
|
||||
|
||||
/* If it's our domain then use the 'password server' parameter. */
|
||||
|
||||
if (strequal(domain, lp_workgroup())) {
|
||||
const char *p;
|
||||
char *pserver = lp_passwordserver();
|
||||
char *p;
|
||||
char *pserver = lp_passwordserver(); /* UNIX charset. */
|
||||
fstring name;
|
||||
int num_adresses = 0;
|
||||
int num_addresses = 0;
|
||||
int local_count, i, j;
|
||||
struct in_addr *return_iplist = NULL;
|
||||
struct in_addr *auto_ip_list = NULL;
|
||||
BOOL done_auto_lookup = False;
|
||||
int auto_count = 0;
|
||||
|
||||
|
||||
if (!*pserver)
|
||||
return internal_resolve_name(
|
||||
@ -1255,19 +1260,31 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count)
|
||||
|
||||
p = pserver;
|
||||
|
||||
/*
|
||||
* if '*' appears in the "password server" list then add
|
||||
* an auto lookup to the list of manually configured
|
||||
* DC's. If any DC is listed by name, then the list should be
|
||||
* considered to be ordered
|
||||
*/
|
||||
|
||||
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
|
||||
if (strequal(name, "*"))
|
||||
return internal_resolve_name(
|
||||
domain, 0x1C, ip_list, count);
|
||||
num_adresses++;
|
||||
if (strequal(name, "*")) {
|
||||
if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
|
||||
num_addresses += auto_count;
|
||||
done_auto_lookup = True;
|
||||
DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
|
||||
}
|
||||
else
|
||||
num_addresses++;
|
||||
}
|
||||
|
||||
if (num_adresses == 0)
|
||||
return internal_resolve_name(
|
||||
domain, 0x1C, ip_list, count);
|
||||
/* if we have no addresses and haven't done the auto lookup, then
|
||||
just return the list of DC's */
|
||||
|
||||
if ( (num_addresses == 0) && !done_auto_lookup )
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count);
|
||||
|
||||
return_iplist = (struct in_addr *)malloc(
|
||||
num_adresses * sizeof(struct in_addr));
|
||||
return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
|
||||
|
||||
if (return_iplist == NULL) {
|
||||
DEBUG(3,("get_dc_list: malloc fail !\n"));
|
||||
@ -1275,19 +1292,84 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count)
|
||||
}
|
||||
|
||||
p = pserver;
|
||||
*count = 0;
|
||||
local_count = 0;
|
||||
|
||||
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
|
||||
/* fill in the return list now with real IP's */
|
||||
|
||||
while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) )
|
||||
{
|
||||
struct in_addr name_ip;
|
||||
if (resolve_name( name, &name_ip, 0x20) == False)
|
||||
|
||||
/* copy any addersses from the auto lookup */
|
||||
|
||||
if ( strequal(name, "*") ) {
|
||||
for ( j=0; j<auto_count; j++ )
|
||||
return_iplist[local_count++] = auto_ip_list[j];
|
||||
continue;
|
||||
return_iplist[(*count)++] = name_ip;
|
||||
}
|
||||
|
||||
/* explicit lookup */
|
||||
|
||||
if ( resolve_name( name, &name_ip, 0x20) ) {
|
||||
return_iplist[local_count++] = name_ip;
|
||||
*ordered = True;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* need to remove duplicates in the list if we have
|
||||
any explicit password servers */
|
||||
|
||||
if ( *ordered )
|
||||
{
|
||||
int hole_index = -1;
|
||||
|
||||
/* one loop to remove duplicates */
|
||||
for ( i=0; i<local_count; i++ )
|
||||
{
|
||||
if ( is_zero_ip(return_iplist[i]) )
|
||||
continue;
|
||||
|
||||
for ( j=i+1; j<local_count; j++ ) {
|
||||
if ( ip_equal( return_iplist[i], return_iplist[j]) )
|
||||
zero_ip(&return_iplist[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/* one loop to clean up any holes we left */
|
||||
/* first ip can never be a zero_ip() */
|
||||
i = 0;
|
||||
while ( i<local_count )
|
||||
{
|
||||
if ( !is_zero_ip(return_iplist[i]) ) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
hole_index = i;
|
||||
i++;
|
||||
|
||||
while ( i<local_count ) {
|
||||
if ( !is_zero_ip(return_iplist[i]) )
|
||||
return_iplist[hole_index++] = return_iplist[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
/* we should exit the loop implicitly here, but ... */
|
||||
break;
|
||||
}
|
||||
|
||||
local_count = hole_index;
|
||||
}
|
||||
|
||||
*ip_list = return_iplist;
|
||||
*count = local_count;
|
||||
|
||||
DEBUG(8,("get_dc_list: return %d ip addresses\n", *count));
|
||||
|
||||
return (*count != 0);
|
||||
}
|
||||
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count);
|
||||
}
|
||||
|
||||
|
@ -142,8 +142,9 @@ static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
|
||||
{
|
||||
struct in_addr *ip_list = NULL;
|
||||
int count, i;
|
||||
BOOL list_ordered;
|
||||
|
||||
if (!get_dc_list(domain, &ip_list, &count)) {
|
||||
if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) {
|
||||
struct in_addr pdc_ip;
|
||||
|
||||
if (!get_pdc_ip(domain, &pdc_ip)) {
|
||||
@ -161,8 +162,8 @@ static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
|
||||
count = 1;
|
||||
}
|
||||
|
||||
/* Pick a nice close server */
|
||||
if (count > 1) {
|
||||
/* Pick a nice close server, but only if the list was not ordered */
|
||||
if (!list_ordered && (count > 1) ) {
|
||||
qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,7 @@ static int net_lookup_dc(int argc, const char **argv)
|
||||
char *pdc_str = NULL;
|
||||
const char *domain=opt_target_workgroup;
|
||||
int count, i;
|
||||
BOOL list_ordered;
|
||||
|
||||
if (argc > 0)
|
||||
domain=argv[0];
|
||||
@ -139,7 +140,7 @@ static int net_lookup_dc(int argc, const char **argv)
|
||||
asprintf(&pdc_str, "%s", inet_ntoa(addr));
|
||||
d_printf("%s\n", pdc_str);
|
||||
|
||||
if (!get_dc_list(domain, &ip_list, &count)) {
|
||||
if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) {
|
||||
SAFE_FREE(pdc_str);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user