mirror of
https://github.com/samba-team/samba.git
synced 2025-08-26 01:49:31 +03:00
r13310: first round of server affinity patches for winbindd & net ads join
(This used to be commit 6c3480f9ae
)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
989c9311c5
commit
855e02f164
@ -238,14 +238,6 @@ typedef struct nttime_info {
|
||||
|
||||
#define MAX_HOURS_LEN 32
|
||||
|
||||
/*
|
||||
* window during which we must talk to the PDC to avoid
|
||||
* sam sync delays; expressed in seconds (15 minutes is the
|
||||
* default period for SAM replication under Windows NT 4.0
|
||||
*/
|
||||
#define SAM_SYNC_WINDOW 900
|
||||
|
||||
|
||||
#ifndef MAXSUBAUTHS
|
||||
#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
|
||||
#endif
|
||||
|
@ -268,7 +268,7 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
|
||||
SAFE_FREE(entry_buf);
|
||||
|
||||
DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
|
||||
"timeout = %s\n", t > time(NULL) ? "valid" :
|
||||
"timeout = %s", t > time(NULL) ? "valid" :
|
||||
"expired", keystr, v, ctime(&t)));
|
||||
|
||||
if (valstr)
|
||||
@ -281,20 +281,18 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
|
||||
|
||||
return t > time(NULL);
|
||||
|
||||
} else {
|
||||
SAFE_FREE(databuf.dptr);
|
||||
}
|
||||
|
||||
if (valstr)
|
||||
*valstr = NULL;
|
||||
SAFE_FREE(databuf.dptr);
|
||||
|
||||
if (timeout)
|
||||
timeout = NULL;
|
||||
if (valstr)
|
||||
*valstr = NULL;
|
||||
if (timeout)
|
||||
timeout = NULL;
|
||||
|
||||
DEBUG(10, ("Cache entry with key = %s couldn't be found\n",
|
||||
keystr));
|
||||
DEBUG(10, ("Cache entry with key = %s couldn't be found\n", keystr));
|
||||
|
||||
return False;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
|
@ -136,6 +136,10 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port)
|
||||
ads->ldap_port = port;
|
||||
ads->ldap_ip = *interpret_addr2(srv);
|
||||
free(srv);
|
||||
|
||||
/* cache the successful connection */
|
||||
|
||||
saf_store( ads->server.workgroup, server );
|
||||
|
||||
return True;
|
||||
}
|
||||
|
@ -865,14 +865,16 @@ BOOL cli_session_setup(struct cli_state *cli,
|
||||
DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status)));
|
||||
return False;
|
||||
}
|
||||
return True;
|
||||
} else {
|
||||
/* otherwise do a NT1 style session setup */
|
||||
if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) {
|
||||
DEBUG(3,("cli_session_setup: NT1 session setup failed!\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise do a NT1 style session setup */
|
||||
return True;
|
||||
|
||||
return cli_session_setup_nt1(cli, user,
|
||||
pass, passlen, ntpass, ntpasslen,
|
||||
workgroup);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -24,6 +24,94 @@
|
||||
/* nmbd.c sets this to True. */
|
||||
BOOL global_in_nmbd = False;
|
||||
|
||||
|
||||
/****************************
|
||||
* SERVER AFFINITY ROUTINES *
|
||||
****************************/
|
||||
|
||||
/* Server affinity is the concept of preferring the last domain
|
||||
controller with whom you had a successful conversation */
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
#define SAFKEY_FMT "SAF/DOMAIN/%s"
|
||||
#define SAF_TTL 900
|
||||
|
||||
static char *saf_key(const char *domain)
|
||||
{
|
||||
char *keystr;
|
||||
|
||||
asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
|
||||
|
||||
return keystr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
BOOL saf_store( const char *domain, const char *servername )
|
||||
{
|
||||
char *key;
|
||||
time_t expire;
|
||||
BOOL ret = False;
|
||||
|
||||
if ( !domain || !servername ) {
|
||||
DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( !gencache_init() )
|
||||
return False;
|
||||
|
||||
key = saf_key( domain );
|
||||
expire = time( NULL ) + SAF_TTL;
|
||||
|
||||
|
||||
DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%d]\n",
|
||||
domain, servername, expire ));
|
||||
|
||||
ret = gencache_set( key, servername, expire );
|
||||
|
||||
SAFE_FREE( key );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
char *saf_fetch( const char *domain )
|
||||
{
|
||||
char *server = NULL;
|
||||
time_t timeout;
|
||||
BOOL ret = False;
|
||||
char *key = NULL;
|
||||
|
||||
if ( !domain ) {
|
||||
DEBUG(2,("saf_fetch: Empty domain name!\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !gencache_init() )
|
||||
return False;
|
||||
|
||||
key = saf_key( domain );
|
||||
|
||||
ret = gencache_get( key, &server, &timeout );
|
||||
|
||||
SAFE_FREE( key );
|
||||
|
||||
if ( !ret ) {
|
||||
DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
|
||||
} else {
|
||||
DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
|
||||
server, domain ));
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Generate a random trn_id.
|
||||
****************************************************************************/
|
||||
@ -1261,6 +1349,18 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
|
||||
int *count, BOOL ads_only, int *ordered)
|
||||
{
|
||||
fstring resolve_order;
|
||||
char *saf_servername;
|
||||
pstring pserver;
|
||||
const char *p;
|
||||
char *port_str;
|
||||
int port;
|
||||
fstring name;
|
||||
int num_addresses = 0;
|
||||
int local_count, i, j;
|
||||
struct ip_service *return_iplist = NULL;
|
||||
struct ip_service *auto_ip_list = NULL;
|
||||
BOOL done_auto_lookup = False;
|
||||
int auto_count = 0;
|
||||
|
||||
/* if we are restricted to solely using DNS for looking
|
||||
up a domain controller, make sure that host lookups
|
||||
@ -1277,148 +1377,145 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
|
||||
fstrcpy( resolve_order, "NULL" );
|
||||
}
|
||||
|
||||
|
||||
*ordered = False;
|
||||
|
||||
/* If it's our domain then use the 'password server' parameter. */
|
||||
|
||||
|
||||
/* fetch the server we have affinity for. Add the
|
||||
'password server' list to a search for our domain controllers */
|
||||
|
||||
saf_servername = saf_fetch( domain );
|
||||
|
||||
if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
|
||||
const char *p;
|
||||
char *pserver = lp_passwordserver(); /* UNIX charset. */
|
||||
char *port_str;
|
||||
int port;
|
||||
fstring name;
|
||||
int num_addresses = 0;
|
||||
int local_count, i, j;
|
||||
struct ip_service *return_iplist = NULL;
|
||||
struct ip_service *auto_ip_list = NULL;
|
||||
BOOL done_auto_lookup = False;
|
||||
int auto_count = 0;
|
||||
|
||||
pstr_sprintf( pserver, "%s, %s",
|
||||
saf_servername ? saf_servername : "",
|
||||
lp_passwordserver() );
|
||||
} else {
|
||||
pstr_sprintf( pserver, "%s, *",
|
||||
saf_servername ? saf_servername : "" );
|
||||
}
|
||||
|
||||
if (!*pserver)
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
|
||||
SAFE_FREE( saf_servername );
|
||||
|
||||
p = pserver;
|
||||
/* if we are starting from scratch, just lookup DOMAIN<0x1c> */
|
||||
|
||||
/*
|
||||
* 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, "*")) {
|
||||
if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
|
||||
num_addresses += auto_count;
|
||||
done_auto_lookup = True;
|
||||
DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
|
||||
} else {
|
||||
num_addresses++;
|
||||
}
|
||||
if ( !*pserver ) {
|
||||
DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
|
||||
}
|
||||
|
||||
DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", 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
|
||||
*/
|
||||
|
||||
p = pserver;
|
||||
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
|
||||
if (strequal(name, "*")) {
|
||||
if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) )
|
||||
num_addresses += auto_count;
|
||||
done_auto_lookup = True;
|
||||
DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
|
||||
} else {
|
||||
num_addresses++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have no addresses and haven't done the auto lookup, then
|
||||
just return the list of DC's */
|
||||
/* if we have no addresses and haven't done the auto lookup, then
|
||||
just return the list of DC's. Or maybe we just failed. */
|
||||
|
||||
if ( (num_addresses == 0) && !done_auto_lookup ) {
|
||||
if ( (num_addresses == 0) ) {
|
||||
if ( !done_auto_lookup ) {
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
|
||||
}
|
||||
|
||||
/* maybe we just failed? */
|
||||
|
||||
if ( num_addresses == 0 ) {
|
||||
DEBUG(4,("get_dc_list: no servers found\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
|
||||
DEBUG(3,("get_dc_list: malloc fail !\n"));
|
||||
} else {
|
||||
DEBUG(4,("get_dc_list: no servers found\n"));
|
||||
return False;
|
||||
}
|
||||
}
|
||||
|
||||
p = pserver;
|
||||
local_count = 0;
|
||||
if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
|
||||
DEBUG(3,("get_dc_list: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* fill in the return list now with real IP's */
|
||||
p = pserver;
|
||||
local_count = 0;
|
||||
|
||||
/* 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;
|
||||
while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
|
||||
struct in_addr name_ip;
|
||||
|
||||
/* copy any addersses from the auto lookup */
|
||||
/* copy any addersses from the auto lookup */
|
||||
|
||||
if ( strequal(name, "*") ) {
|
||||
for ( j=0; j<auto_count; j++ ) {
|
||||
/* Check for and don't copy any known bad DC IP's. */
|
||||
if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
|
||||
inet_ntoa(auto_ip_list[j].ip)))) {
|
||||
DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
|
||||
inet_ntoa(auto_ip_list[j].ip) ));
|
||||
continue;
|
||||
}
|
||||
return_iplist[local_count].ip = auto_ip_list[j].ip;
|
||||
return_iplist[local_count].port = auto_ip_list[j].port;
|
||||
local_count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* added support for address:port syntax for ads (not that I think
|
||||
anyone will ever run the LDAP server in an AD domain on something
|
||||
other than port 389 */
|
||||
|
||||
port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
|
||||
if ( (port_str=strchr(name, ':')) != NULL ) {
|
||||
*port_str = '\0';
|
||||
port_str++;
|
||||
port = atoi( port_str );
|
||||
}
|
||||
|
||||
/* explicit lookup; resolve_name() will handle names & IP addresses */
|
||||
if ( resolve_name( name, &name_ip, 0x20 ) ) {
|
||||
|
||||
if ( strequal(name, "*") ) {
|
||||
for ( j=0; j<auto_count; j++ ) {
|
||||
/* Check for and don't copy any known bad DC IP's. */
|
||||
if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
|
||||
DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
|
||||
if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
|
||||
inet_ntoa(auto_ip_list[j].ip)))) {
|
||||
DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
|
||||
inet_ntoa(auto_ip_list[j].ip) ));
|
||||
continue;
|
||||
}
|
||||
|
||||
return_iplist[local_count].ip = name_ip;
|
||||
return_iplist[local_count].port = port;
|
||||
return_iplist[local_count].ip = auto_ip_list[j].ip;
|
||||
return_iplist[local_count].port = auto_ip_list[j].port;
|
||||
local_count++;
|
||||
*ordered = True;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(auto_ip_list);
|
||||
|
||||
/* need to remove duplicates in the list if we have any
|
||||
explicit password servers */
|
||||
|
||||
if ( local_count ) {
|
||||
local_count = remove_duplicate_addrs2( return_iplist, local_count );
|
||||
}
|
||||
|
||||
if ( DEBUGLEVEL >= 4 ) {
|
||||
DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
|
||||
*ordered ? "":"un"));
|
||||
DEBUG(4,("get_dc_list: "));
|
||||
for ( i=0; i<local_count; i++ )
|
||||
DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
|
||||
DEBUGADD(4,("\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
*ip_list = return_iplist;
|
||||
*count = local_count;
|
||||
|
||||
/* added support for address:port syntax for ads (not that I think
|
||||
anyone will ever run the LDAP server in an AD domain on something
|
||||
other than port 389 */
|
||||
|
||||
port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
|
||||
if ( (port_str=strchr(name, ':')) != NULL ) {
|
||||
*port_str = '\0';
|
||||
port_str++;
|
||||
port = atoi( port_str );
|
||||
}
|
||||
|
||||
return (*count != 0);
|
||||
/* explicit lookup; resolve_name() will handle names & IP addresses */
|
||||
if ( resolve_name( name, &name_ip, 0x20 ) ) {
|
||||
|
||||
/* Check for and don't copy any known bad DC IP's. */
|
||||
if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
|
||||
DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
|
||||
continue;
|
||||
}
|
||||
|
||||
return_iplist[local_count].ip = name_ip;
|
||||
return_iplist[local_count].port = port;
|
||||
local_count++;
|
||||
*ordered = True;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain));
|
||||
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);
|
||||
|
||||
SAFE_FREE(auto_ip_list);
|
||||
|
||||
/* need to remove duplicates in the list if we have any
|
||||
explicit password servers */
|
||||
|
||||
if ( local_count ) {
|
||||
local_count = remove_duplicate_addrs2( return_iplist, local_count );
|
||||
}
|
||||
|
||||
if ( DEBUGLEVEL >= 4 ) {
|
||||
DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
|
||||
*ordered ? "":"un"));
|
||||
DEBUG(4,("get_dc_list: "));
|
||||
for ( i=0; i<local_count; i++ )
|
||||
DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
|
||||
DEBUGADD(4,("\n"));
|
||||
}
|
||||
|
||||
*ip_list = return_iplist;
|
||||
*count = local_count;
|
||||
|
||||
return (*count != 0);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
@ -75,31 +75,10 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
|
||||
struct ip_service *ip_list = NULL;
|
||||
struct in_addr dc_ip, exclude_ip;
|
||||
int count, i;
|
||||
BOOL use_pdc_only;
|
||||
NTSTATUS result;
|
||||
|
||||
zero_ip(&exclude_ip);
|
||||
|
||||
use_pdc_only = must_use_pdc(domain);
|
||||
|
||||
/* Lookup domain controller name */
|
||||
|
||||
if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) )
|
||||
{
|
||||
DEBUG(10,("rpc_dc_name: Atempting to lookup PDC to avoid sam sync delays\n"));
|
||||
|
||||
/* check the connection cache and perform the node status
|
||||
lookup only if the IP is not found to be bad */
|
||||
|
||||
if (name_status_find(domain, 0x1b, 0x20, dc_ip, srv_name) ) {
|
||||
result = check_negative_conn_cache( domain, srv_name );
|
||||
if ( NT_STATUS_IS_OK(result) )
|
||||
goto done;
|
||||
}
|
||||
/* Didn't get name, remember not to talk to this DC. */
|
||||
exclude_ip = dc_ip;
|
||||
}
|
||||
|
||||
/* get a list of all domain controllers */
|
||||
|
||||
if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
|
||||
@ -109,13 +88,6 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip
|
||||
|
||||
/* Remove the entry we've already failed with (should be the PDC). */
|
||||
|
||||
if ( use_pdc_only ) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (ip_equal( exclude_ip, ip_list[i].ip))
|
||||
zero_ip(&ip_list[i].ip);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (is_zero_ip(ip_list[i].ip))
|
||||
continue;
|
||||
|
@ -358,6 +358,10 @@ static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
|
||||
|
||||
session_setup_done:
|
||||
|
||||
/* cache the server name for later connections */
|
||||
|
||||
saf_store( (*cli)->domain, (*cli)->desthost );
|
||||
|
||||
if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
|
||||
|
||||
result = cli_nt_error(*cli);
|
||||
@ -658,14 +662,6 @@ static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
|
||||
return True;
|
||||
}
|
||||
|
||||
if ( is_our_domain
|
||||
&& must_use_pdc(domain->name)
|
||||
&& get_pdc_ip(domain->name, &ip))
|
||||
{
|
||||
if (add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip), ip, dcs, num_dcs))
|
||||
return True;
|
||||
}
|
||||
|
||||
/* try standard netbios queries first */
|
||||
|
||||
get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
|
||||
@ -752,12 +748,35 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
|
||||
{
|
||||
TALLOC_CTX *mem_ctx;
|
||||
NTSTATUS result;
|
||||
|
||||
char *saf_servername = saf_fetch( domain->name );
|
||||
int retries;
|
||||
|
||||
if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
/* we have to check the server affinity cache here since
|
||||
later we selecte a DC based on response time and not preference */
|
||||
|
||||
if ( saf_servername )
|
||||
{
|
||||
/* convert an ip address to a name */
|
||||
if ( is_ipaddress( saf_servername ) )
|
||||
{
|
||||
fstring saf_name;
|
||||
struct in_addr ip;
|
||||
|
||||
ip = *interpret_addr2( saf_servername );
|
||||
dcip_to_name( domain->name, domain->alt_name, &domain->sid, ip, saf_name );
|
||||
fstrcpy( domain->dcname, saf_name );
|
||||
}
|
||||
else
|
||||
{
|
||||
fstrcpy( domain->dcname, saf_servername );
|
||||
}
|
||||
|
||||
SAFE_FREE( saf_servername );
|
||||
}
|
||||
|
||||
for (retries = 0; retries < 3; retries++) {
|
||||
|
||||
int fd = -1;
|
||||
@ -765,27 +784,28 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
|
||||
|
||||
result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
|
||||
|
||||
if ((strlen(domain->dcname) > 0) &&
|
||||
NT_STATUS_IS_OK(check_negative_conn_cache(
|
||||
domain->name, domain->dcname)) &&
|
||||
(resolve_name(domain->dcname, &domain->dcaddr.sin_addr,
|
||||
0x20))) {
|
||||
int dummy;
|
||||
struct sockaddr_in addrs[2];
|
||||
addrs[0] = domain->dcaddr;
|
||||
addrs[0].sin_port = htons(445);
|
||||
addrs[1] = domain->dcaddr;
|
||||
addrs[1].sin_port = htons(139);
|
||||
if (!open_any_socket_out(addrs, 2, 10000,
|
||||
&dummy, &fd)) {
|
||||
if ((strlen(domain->dcname) > 0)
|
||||
&& NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
|
||||
&& (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
|
||||
{
|
||||
struct sockaddr_in *addrs = NULL;
|
||||
int num_addrs = 0;
|
||||
int dummy = 0;
|
||||
|
||||
|
||||
add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs);
|
||||
add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs);
|
||||
|
||||
if (!open_any_socket_out(addrs, num_addrs, 10000, &dummy, &fd)) {
|
||||
fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fd == -1) &&
|
||||
!find_new_dc(mem_ctx, domain, domain->dcname,
|
||||
&domain->dcaddr, &fd))
|
||||
if ((fd == -1)
|
||||
&& !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
new_conn->cli = NULL;
|
||||
|
||||
|
@ -821,35 +821,6 @@ void secrets_named_mutex_release(const char *name)
|
||||
DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
Check to see if we must talk to the PDC to avoid sam
|
||||
sync delays
|
||||
********************************************************/
|
||||
|
||||
BOOL must_use_pdc( const char *domain )
|
||||
{
|
||||
time_t now = time(NULL);
|
||||
time_t last_change_time;
|
||||
unsigned char passwd[16];
|
||||
|
||||
if ( !secrets_fetch_trust_account_password(domain, passwd, &last_change_time, NULL) )
|
||||
return False;
|
||||
|
||||
/*
|
||||
* If the time the machine password has changed
|
||||
* was less than about 15 minutes then we need to contact
|
||||
* the PDC only, as we cannot be sure domain replication
|
||||
* has yet taken place. Bug found by Gerald (way to go
|
||||
* Gerald !). JRA.
|
||||
*/
|
||||
|
||||
if ( now - last_change_time < SAM_SYNC_WINDOW )
|
||||
return True;
|
||||
|
||||
return False;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Store a complete AFS keyfile into secrets.tdb.
|
||||
*******************************************************************************/
|
||||
|
Reference in New Issue
Block a user