diff options
-rw-r--r-- | source3/include/proto.h | 2 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 4 | ||||
-rw-r--r-- | source3/rpc_client/cli_netlogon.c | 3 | ||||
-rw-r--r-- | source3/smbd/password.c | 22 |
4 files changed, 23 insertions, 8 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index d54f26dd0b..168600a59f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -856,7 +856,7 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, struct in_addr *ip); BOOL find_master_ip(char *group, struct in_addr *master_ip); BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); +BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count); /*The following definitions come from libsmb/nmblib.c */ diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a8cc2fcf3a..fa90691a95 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1063,7 +1063,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. *********************************************************/ -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count) +BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count) { - return internal_resolve_name(group, 0x1C, ip_list, count); + return internal_resolve_name(group, pdc_only ? 0x1B : 0x1C, ip_list, count); } diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 63461c5023..3e24e74a59 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -665,7 +665,8 @@ account password for domain %s.\n", domain)); int count = 0; int i; - if(!get_dc_list(domain, &ip_list, &count)) + /* Use the PDC *only* for this. */ + if(!get_dc_list(True, domain, &ip_list, &count)) continue; /* diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1924bf3217..c2bcac339e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1344,14 +1344,27 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un We have been asked to dynamcially determine the IP addresses of the PDC and BDC's for this DOMAIN, and query them in turn. ************************************************************************/ -static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd) +static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd, time_t last_change_time) { struct in_addr *ip_list = NULL; int count = 0; int i; BOOL connected_ok = False; + time_t time_now = time(NULL); + BOOL use_pdc_only = False; - if (!get_dc_list(lp_workgroup(), &ip_list, &count)) + /* + * If the time the machine password has changed + * was less than an hour ago 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 (time_now - last_change_time < 3600) + use_pdc_only = True; + + if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) return False; /* @@ -1423,6 +1436,7 @@ BOOL domain_client_validate( char *user, char *domain, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; + time_t last_change_time; if(user_exists != NULL) *user_exists = True; /* Only set false on a very specific error. */ @@ -1473,7 +1487,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) { DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); return False; @@ -1501,7 +1515,7 @@ BOOL domain_client_validate( char *user, char *domain, while (!connected_ok && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { if(strequal(remote_machine, "*")) { - connected_ok = find_connect_pdc(&cli, trust_passwd); + connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); } else { connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); } |