From 899b6e6d0facd1ef5865ce550fadd292514955d6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 13 Dec 2002 02:07:05 +0000 Subject: merge of get_dc_name()-like code from APP_HEAD; better support password server = DC1 * (This used to be commit f49de4c5176bf635ac080e082fda412066b466c8) --- source3/Makefile.in | 4 +- source3/auth/auth_domain.c | 96 ++++-------------------------------------- source3/include/smb.h | 8 ++++ source3/nsswitch/winbindd_cm.c | 50 +--------------------- source3/passdb/secrets.c | 30 +++++++++++++ 5 files changed, 49 insertions(+), 139 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index acf88cbf3e..d7147cb4d6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -193,7 +193,7 @@ LIBMSRPC_OBJ = rpc_client/cli_lsarpc.o rpc_client/cli_samr.o \ rpc_client/cli_wkssvc.o rpc_client/cli_dfs.o \ rpc_client/cli_reg.o rpc_client/cli_pipe.o \ rpc_client/cli_spoolss.o rpc_client/cli_spoolss_notify.o \ - rpc_client/cli_ds.o + rpc_client/cli_ds.o libsmb/namequery_dc.o LIBMSRPC_SERVER_OBJ = libsmb/trust_passwd.o @@ -458,7 +458,7 @@ LOCKTEST2_OBJ = torture/locktest2.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \ SMBCACLS_OBJ = utils/smbcacls.o $(LOCKING_OBJ) $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_GET_SET_OBJ) \ - $(LIBMSRPC_OBJ) + $(LIBMSRPC_OBJ) $(SECRETS_OBJ) TALLOCTORT_OBJ = lib/talloctort.o $(LIB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index eebe647ec0..8c56b4484e 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -262,103 +262,23 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, We have been asked to dynamically determine the IP addresses of the PDC and BDC's for DOMAIN, and query them in turn. ************************************************************************/ -static NTSTATUS find_connect_pdc(struct cli_state **cli, +static NTSTATUS find_connect_dc(struct cli_state **cli, const char *domain, const char *setup_creds_as, uint16 sec_chan, unsigned char *trust_passwd, time_t last_change_time) { - struct in_addr *ip_list = NULL; - int count = 0; - int i; - 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 - * 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 (use_pdc_only) { - struct in_addr pdc_ip; + struct in_addr dc_ip; + fstring srv_name; - if (!get_pdc_ip(domain, &pdc_ip)) - return NT_STATUS_NO_LOGON_SERVERS; - - if ((ip_list = (struct in_addr *) - malloc(sizeof(struct in_addr))) == NULL) - return NT_STATUS_NO_MEMORY; - - ip_list[0] = pdc_ip; - count = 1; - - } else { - if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) + if ( !rpc_find_dc(lp_workgroup(), srv_name, &dc_ip) ) { + DEBUG(0,("find_connect_dc: Failed to find an DCs for %s\n", lp_workgroup())); return NT_STATUS_NO_LOGON_SERVERS; } - /* - * Firstly try and contact a PDC/BDC who has the same - * network address as any of our interfaces. - */ - for(i = 0; i < count; i++) { - if( !list_ordered && !is_local_net(ip_list[i]) ) - continue; - - if(NT_STATUS_IS_OK(nt_status = - attempt_connect_to_dc(cli, domain, - &ip_list[i], setup_creds_as, - sec_chan, trust_passwd))) - break; - - zero_ip(&ip_list[i]); /* Tried and failed. */ - } - - /* - * Secondly try and contact a random PDC/BDC. - */ - if(!NT_STATUS_IS_OK(nt_status)) { - i = (sys_random() % count); - - if (!is_zero_ip(ip_list[i])) { - if (!NT_STATUS_IS_OK(nt_status = - attempt_connect_to_dc(cli, domain, - &ip_list[i], setup_creds_as, - sec_chan, trust_passwd))) - zero_ip(&ip_list[i]); /* Tried and failed. */ - } - } - - /* - * Finally go through the IP list in turn, ignoring any addresses - * we have already tried. - */ - if(!NT_STATUS_IS_OK(nt_status)) { - /* - * Try and connect to any of the other IP addresses in the PDC/BDC list. - * Note that from a WINS server the #1 IP address is the PDC. - */ - for(i = 0; i < count; i++) { - if (is_zero_ip(ip_list[i])) - continue; - - if (NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, domain, - &ip_list[i], setup_creds_as, sec_chan, trust_passwd))) - break; - } - } - - SAFE_FREE(ip_list); - return nt_status; + return attempt_connect_to_dc( cli, domain, &dc_ip, setup_creds_as, + sec_chan, trust_passwd ); } /*********************************************************************** @@ -393,7 +313,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, while (!NT_STATUS_IS_OK(nt_status) && next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) { - nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time); + nt_status = find_connect_dc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time); } else { int i; BOOL retry = True; diff --git a/source3/include/smb.h b/source3/include/smb.h index de0f10b3c5..b389020e23 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -221,6 +221,14 @@ 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 diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 403bc38052..075da1e2b2 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -135,54 +135,6 @@ static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr return True; } -/* - find the DC for a domain using methods appropriate for a RPC domain -*/ -static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name) -{ - struct in_addr *ip_list = NULL; - int count, i; - BOOL list_ordered; - - if (!get_dc_list(domain, &ip_list, &count, &list_ordered)) { - struct in_addr pdc_ip; - - if (!get_pdc_ip(domain, &pdc_ip)) { - DEBUG(3, ("Could not look up any DCs for domain %s\n", - domain)); - return False; - } - - ip_list = (struct in_addr *)malloc(sizeof(struct in_addr)); - - if (!ip_list) - return False; - - ip_list[0] = pdc_ip; - 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); - } - - for (i = 0; i < count; i++) { - if (is_zero_ip(ip_list[i])) - continue; - - if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { - *dc_ip = ip_list[i]; - SAFE_FREE(ip_list); - return True; - } - } - - - SAFE_FREE(ip_list); - - return False; -} static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) @@ -247,7 +199,7 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name, struct in_addr } if (!ret) { /* fall back on rpc methods if the ADS methods fail */ - ret = cm_rpc_find_dc(domain, &dc_ip, srv_name); + ret = rpc_find_dc(domain, srv_name, &dc_ip); } if (!ret) { diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c index 29afaddea3..b93ea74d8b 100644 --- a/source3/passdb/secrets.c +++ b/source3/passdb/secrets.c @@ -610,3 +610,33 @@ void secrets_named_mutex_release(const char *name) tdb_unlock_bystring(tdb, 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) ) + 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; + +} + -- cgit