diff options
author | Gerald Carter <jerry@samba.org> | 2003-06-25 17:41:05 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2003-06-25 17:41:05 +0000 |
commit | f51d769dd303027a3dbf46fc89a482933988e866 (patch) | |
tree | 5bb400a9df1f6fb27f2b045a6521e2995de8c686 /source3/libads/ldap.c | |
parent | eb61c8238298e97644202139e6d7f55e46eb9c26 (diff) | |
download | samba-f51d769dd303027a3dbf46fc89a482933988e866.tar.gz samba-f51d769dd303027a3dbf46fc89a482933988e866.tar.xz samba-f51d769dd303027a3dbf46fc89a482933988e866.zip |
large change:
*) consolidates the dc location routines again (dns
and netbios) get_dc_list() or get_sorted_dc_list()
is the authoritative means of locating DC's again.
(also inludes a flag to get_dc_list() to define
if this should be a DNS only lookup or not)
(however, if you set "name resolve order = hosts wins"
you could still get DNS queries for domain name IFF
ldap_domain2hostlist() fails. The answer? Fix your DNS
setup)
*) enabled DOMAIN<0x1c> lookups to be funneled through
resolve_hosts resulting in a call to ldap_domain2hostlist()
if lp_security() == SEC_ADS
*) enables name cache for winbind ADS backend
*) enable the negative connection cache for winbind
ADS backend
*) removes some old dead code
*) consolidates some duplicate code
*) moves the internal_name_resolve() to use an IP/port pair
to deal with SRV RR dns replies. The namecache code
also supports the IP:port syntax now as well.
*) removes 'ads server' and moves the functionality back
into 'password server' (which can support "hostname:port"
syntax now but works fine with defaults depending on
the value of lp_security())
(This used to be commit d7f7fcda425bef380441509734eca33da943c091)
Diffstat (limited to 'source3/libads/ldap.c')
-rw-r--r-- | source3/libads/ldap.c | 165 |
1 files changed, 47 insertions, 118 deletions
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 0f1f205f9b9..a168f75e989 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -93,133 +93,75 @@ static BOOL ads_try_connect_uri(ADS_STRUCT *ads) return False; } -/* used by the IP comparison function */ -struct ldap_ip { - struct in_addr ip; - unsigned port; -}; - -/* compare 2 ldap IPs by nearness to our interfaces - used in qsort */ -static int ldap_ip_compare(struct ldap_ip *ip1, struct ldap_ip *ip2) -{ - return ip_compare(&ip1->ip, &ip2->ip); -} +/********************************************************************** + Try to find an AD dc using our internal name resolution routines + Try the realm first and then then workgroup name if netbios is not + disabled +**********************************************************************/ -/* try connecting to a ldap server via DNS */ -static BOOL ads_try_dns(ADS_STRUCT *ads) +static BOOL ads_find_dc(ADS_STRUCT *ads) { const char *c_realm; - const char *ptr; - char *realm; - char *list = NULL; - pstring tok; - struct ldap_ip *ip_list; int count, i=0; + struct ip_service *ip_list; + pstring realm; + BOOL got_realm = False; + /* realm */ c_realm = ads->server.realm; if (!c_realm || !*c_realm) { c_realm = lp_realm(); } - if (!c_realm || !*c_realm) { - c_realm = ads->server.workgroup; - } - if (!c_realm || !*c_realm) { - c_realm = lp_workgroup(); - } - if (!c_realm) { - return False; - } - realm = smb_xstrdup(c_realm); + if ( c_realm ) + got_realm = True; - DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm)); - if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) { - SAFE_FREE(realm); - return False; + +again: + /* we need to try once with the realm name and fallback to the + netbios domain name if we fail (if netbios has not been disabled */ + + if ( !got_realm && !lp_disable_netbios() ) { + c_realm = ads->server.workgroup; + if (!c_realm || !*c_realm) + c_realm = lp_workgroup(); + if (!c_realm) + return False; } + + pstrcpy( realm, c_realm ); - DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list)); - SAFE_FREE(realm); - - count = count_chars(list, ' ') + 1; - ip_list = malloc(count * sizeof(struct ldap_ip)); - if (!ip_list) { - return False; - } + DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n", + (got_realm ? "realm" : "domain"), realm)); - ptr = list; - while (next_token(&ptr, tok, " ", sizeof(tok))) { - unsigned port = LDAP_PORT; - char *p = strchr(tok, ':'); - if (p) { - *p = 0; - port = atoi(p+1); - } - ip_list[i].ip = *interpret_addr2(tok); - ip_list[i].port = port; - if (!is_zero_ip(ip_list[i].ip)) { - i++; + if ( !get_sorted_dc_list(realm, &ip_list, &count, got_realm) ) { + /* fall back to netbios if we can */ + if ( got_realm && !lp_disable_netbios() ) { + got_realm = False; + goto again; } + + return False; } - free(list); - - count = i; - - /* we sort the list of addresses by closeness to our interfaces. This - tries to prevent us using a DC on the other side of the country */ - if (count > 1) { - qsort(ip_list, count, sizeof(struct ldap_ip), - QSORT_CAST ldap_ip_compare); - } - - for (i=0;i<count;i++) { - if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) { - free(ip_list); + + /* if we fail this loop, then giveup since all the IP addresses returned were dead */ + for ( i=0; i<count; i++ ) { + /* since this is an ads conection request, default to LDAP_PORT is not set */ + int port = (ip_list[i].port!=PORT_NONE) ? ip_list[i].port : LDAP_PORT; + + if ( ads_try_connect(ads, inet_ntoa(ip_list[i].ip), port) ) { + SAFE_FREE(ip_list); return True; } + + /* keep track of failures */ + add_failed_connection_entry( realm, inet_ntoa(ip_list[i].ip), NT_STATUS_UNSUCCESSFUL ); } SAFE_FREE(ip_list); + return False; } -/* try connecting to a ldap server via netbios */ -static BOOL ads_try_netbios(ADS_STRUCT *ads) -{ - struct in_addr *ip_list, pdc_ip; - int count; - int i; - const char *workgroup = ads->server.workgroup; - BOOL list_ordered; - - if (!workgroup) { - workgroup = lp_workgroup(); - } - - DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup)); - - /* try the PDC first */ - if (get_pdc_ip(workgroup, &pdc_ip)) { - DEBUG(6,("ads_try_netbios: trying server '%s'\n", - inet_ntoa(pdc_ip))); - if (ads_try_connect(ads, inet_ntoa(pdc_ip), LDAP_PORT)) - return True; - } - - /* now any DC, including backups */ - 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]))); - if (ads_try_connect(ads, inet_ntoa(ip_list[i]), LDAP_PORT)) { - free(ip_list); - return True; - } - } - free(ip_list); - } - - return False; -} /** * Connect to the LDAP server @@ -247,20 +189,7 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads) goto got_connection; } - /* try with a smb.conf ads server setting if we are connecting - to the primary workgroup or realm */ - if (!ads->server.foreign && - ads_try_connect(ads, lp_ads_server(), LDAP_PORT)) { - goto got_connection; - } - - /* try via DNS */ - if (ads_try_dns(ads)) { - goto got_connection; - } - - /* try via netbios lookups */ - if (!lp_disable_netbios() && ads_try_netbios(ads)) { + if (ads_find_dc(ads)) { goto got_connection; } |