mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
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 commit is contained in:
parent
57617a0f8c
commit
d7f7fcda42
@ -34,6 +34,7 @@ PASSDBLIBS=@PASSDBLIBS@
|
||||
IDMAP_LIBS=@IDMAP_LIBS@
|
||||
ADSLIBS=@ADSLIBS@
|
||||
KRB5LIBS=@KRB5_LIBS@
|
||||
LDAPLIBS=@LDAP_LIBS@
|
||||
|
||||
LINK=$(CC) $(FLAGS) $(LDFLAGS)
|
||||
|
||||
@ -207,7 +208,7 @@ LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o
|
||||
SECRETS_OBJ = passdb/secrets.o
|
||||
|
||||
LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \
|
||||
libsmb/namequery.o
|
||||
libsmb/namequery.o libsmb/conncache.o
|
||||
|
||||
LIBSAMBA_OBJ = libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o libsmb/ntlmssp.o libsmb/ntlmssp_parse.o libsmb/ntlmssp_sign.o
|
||||
|
||||
@ -732,7 +733,7 @@ bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
|
||||
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/wrepld@EXEEXT@: $(WREPL_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -749,7 +750,7 @@ bin/rpcclient@EXEEXT@: $(RPCCLIENT_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
|
||||
bin/smbclient@EXEEXT@: $(CLIENT_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/net@EXEEXT@: $(NET_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -765,7 +766,7 @@ bin/editreg@EXEEXT@: $(EDITREG_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
|
||||
bin/smbspool@EXEEXT@: $(CUPS_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS) $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/smbmount@EXEEXT@: $(MOUNT_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -797,7 +798,7 @@ bin/smbcontrol@EXEEXT@: $(SMBCONTROL_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
|
||||
bin/smbtree@EXEEXT@: $(SMBTREE_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBTREE_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/smbpasswd@EXEEXT@: $(SMBPASSWD_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -813,7 +814,7 @@ bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
|
||||
bin/nmblookup@EXEEXT@: $(NMBLOOKUP_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@
|
||||
@$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(LDAPLIBS)
|
||||
|
||||
bin/smbtorture@EXEEXT@: $(SMBTORTURE_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -833,11 +834,11 @@ bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy
|
||||
|
||||
bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo Linking $@
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS)
|
||||
@$(CC) $(FLAGS) -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAPLIBS)
|
||||
|
||||
bin/locktest@EXEEXT@: $(LOCKTEST_OBJ) bin/.dummy
|
||||
@echo Linking $@
|
||||
@ -954,7 +955,7 @@ bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
|
||||
|
||||
bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
|
||||
@echo "Linking $@"
|
||||
@$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) @LDAP_LIBS@
|
||||
@$(LINK) -o $@ $(WINBINDD_OBJ) $(DYNEXP) $(LIBS) @POPTLIBS@ $(ADSLIBS) $(LDAPLIBS)
|
||||
|
||||
@WINBIND_NSS@: $(WINBIND_NSS_PICOBJS)
|
||||
@echo "Linking $@"
|
||||
@ -1006,7 +1007,7 @@ bin/mysql.@SHLIBEXT@: $(MYSQL_OBJ:.o=.po)
|
||||
|
||||
bin/ldapsam.@SHLIBEXT@: passdb/pdb_ldap.po
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD) $(LDSHFLAGS) @LDAP_LIBS@ -o $@ passdb/pdb_ldap.po \
|
||||
@$(SHLD) $(LDSHFLAGS) $(LDAPLIBS) -o $@ passdb/pdb_ldap.po \
|
||||
@SONAMEFLAG@`basename $@`
|
||||
|
||||
bin/tdbsam.@SHLIBEXT@: passdb/pdb_tdb.po
|
||||
|
@ -253,7 +253,7 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
|
||||
if (is_zero_ip(*ip))
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
if (!lookup_dc_name(global_myname(), domain, ip, dc_name))
|
||||
if ( !name_status_find( domain, 0x1b, 0x20, *ip, dc_name) )
|
||||
return NT_STATUS_NO_LOGON_SERVERS;
|
||||
|
||||
for (i = 0; (!NT_STATUS_IS_OK(ret)) && retry && (i < 3); i++)
|
||||
|
@ -1618,4 +1618,12 @@ typedef struct {
|
||||
|
||||
#include "popt_common.h"
|
||||
|
||||
#define PORT_NONE 0
|
||||
|
||||
/* used by the IP comparison function */
|
||||
struct ip_service {
|
||||
struct in_addr ip;
|
||||
unsigned port;
|
||||
};
|
||||
|
||||
#endif /* _SMB_H */
|
||||
|
@ -202,6 +202,7 @@ true if two IP addresses are equal
|
||||
****************************************************************************/
|
||||
|
||||
#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
|
||||
#define ip_service_equal(ip1,ip2) ( ((ip1).ip.s_addr == (ip2).ip.s_addr) && ((ip1).port == (ip2).port) )
|
||||
|
||||
/*****************************************************************
|
||||
splits out the last subkey of a key
|
||||
|
@ -2467,6 +2467,7 @@ BOOL unix_wild_match(const char *pattern, const char *string)
|
||||
return unix_do_match(p2, s2) == 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __INSURE__
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -38,6 +38,7 @@
|
||||
BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
|
||||
{
|
||||
const char *s;
|
||||
char *pbuf;
|
||||
BOOL quoted;
|
||||
size_t len=1;
|
||||
|
||||
@ -59,17 +60,18 @@ BOOL next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
|
||||
return(False);
|
||||
|
||||
/* copy over the token */
|
||||
pbuf = buff;
|
||||
for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
|
||||
if (*s == '\"') {
|
||||
quoted = !quoted;
|
||||
} else {
|
||||
len++;
|
||||
*buff++ = *s;
|
||||
*pbuf++ = *s;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr = (*s) ? s+1 : s;
|
||||
*buff = 0;
|
||||
*pbuf = 0;
|
||||
|
||||
return(True);
|
||||
}
|
||||
@ -1469,6 +1471,7 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
|
||||
|
||||
|
||||
#define IPSTR_LIST_SEP ","
|
||||
#define IPSTR_LIST_CHAR ','
|
||||
|
||||
/**
|
||||
* Add ip string representation to ipstr list. Used also
|
||||
@ -1483,19 +1486,20 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
|
||||
* reallocated to new length
|
||||
**/
|
||||
|
||||
char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
|
||||
char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
|
||||
{
|
||||
char* new_ipstr = NULL;
|
||||
|
||||
/* arguments checking */
|
||||
if (!ipstr_list || !ip) return NULL;
|
||||
if (!ipstr_list || !service) return NULL;
|
||||
|
||||
/* attempt to convert ip to a string and append colon separator to it */
|
||||
if (*ipstr_list) {
|
||||
asprintf(&new_ipstr, "%s%s%s", *ipstr_list, IPSTR_LIST_SEP,inet_ntoa(*ip));
|
||||
asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
|
||||
inet_ntoa(service->ip), service->port);
|
||||
SAFE_FREE(*ipstr_list);
|
||||
} else {
|
||||
asprintf(&new_ipstr, "%s", inet_ntoa(*ip));
|
||||
asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
|
||||
}
|
||||
*ipstr_list = new_ipstr;
|
||||
return *ipstr_list;
|
||||
@ -1512,7 +1516,7 @@ char* ipstr_list_add(char** ipstr_list, const struct in_addr *ip)
|
||||
* @return pointer to allocated ip string
|
||||
**/
|
||||
|
||||
char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_count)
|
||||
char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1531,7 +1535,8 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
|
||||
|
||||
/**
|
||||
* Parse given ip string list into array of ip addresses
|
||||
* (as in_addr structures)
|
||||
* (as ip_service structures)
|
||||
* e.g. 192.168.1.100:389,192.168.1.78, ...
|
||||
*
|
||||
* @param ipstr ip string list to be parsed
|
||||
* @param ip_list pointer to array of ip addresses which is
|
||||
@ -1539,28 +1544,40 @@ char* ipstr_list_make(char** ipstr_list, const struct in_addr* ip_list, int ip_c
|
||||
* @return number of succesfully parsed addresses
|
||||
**/
|
||||
|
||||
int ipstr_list_parse(const char* ipstr_list, struct in_addr** ip_list)
|
||||
int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
|
||||
{
|
||||
fstring token_str;
|
||||
int count;
|
||||
size_t count;
|
||||
int i;
|
||||
|
||||
if (!ipstr_list || !ip_list) return 0;
|
||||
if (!ipstr_list || !ip_list)
|
||||
return 0;
|
||||
|
||||
for (*ip_list = NULL, count = 0;
|
||||
next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN);
|
||||
count++) {
|
||||
count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
|
||||
if ( (*ip_list = (struct ip_service*)malloc(count * sizeof(struct ip_service))) == NULL ) {
|
||||
DEBUG(0,("ipstr_list_parse: malloc failed for %d entries\n", count));
|
||||
return 0;
|
||||
}
|
||||
|
||||
for ( i=0;
|
||||
next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count;
|
||||
i++ )
|
||||
{
|
||||
struct in_addr addr;
|
||||
unsigned port = 0;
|
||||
char *p = strchr(token_str, ':');
|
||||
|
||||
if (p) {
|
||||
*p = 0;
|
||||
port = atoi(p+1);
|
||||
}
|
||||
|
||||
/* convert single token to ip address */
|
||||
if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
|
||||
break;
|
||||
|
||||
/* prepare place for another in_addr structure */
|
||||
*ip_list = Realloc(*ip_list, (count + 1) * sizeof(struct in_addr));
|
||||
if (!*ip_list) return -1;
|
||||
|
||||
(*ip_list)[count] = addr;
|
||||
(*ip_list)[i].ip = addr;
|
||||
(*ip_list)[i].port = port;
|
||||
}
|
||||
|
||||
return count;
|
||||
|
@ -70,14 +70,24 @@
|
||||
|
||||
static char *wins_srv_keystr(struct in_addr wins_ip, struct in_addr src_ip)
|
||||
{
|
||||
char *keystr;
|
||||
char *keystr = NULL, *wins_ip_addr = NULL, *src_ip_addr = NULL;
|
||||
|
||||
if (asprintf(&keystr, WINS_SRV_FMT, inet_ntoa(wins_ip),
|
||||
inet_ntoa(src_ip)) == -1) {
|
||||
DEBUG(0, ("wins_srv_is_dead: malloc error\n"));
|
||||
return NULL;
|
||||
wins_ip_addr = strdup(inet_ntoa(wins_ip));
|
||||
src_ip_addr = strdup(inet_ntoa(src_ip));
|
||||
|
||||
if ( !wins_ip_addr || !src_ip_addr ) {
|
||||
DEBUG(0,("wins_srv_keystr: malloc error\n"));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (asprintf(&keystr, WINS_SRV_FMT, wins_ip_addr, src_ip_addr) == -1) {
|
||||
DEBUG(0, (": ns_srv_keystr: malloc error for key string\n"));
|
||||
}
|
||||
|
||||
done:
|
||||
SAFE_FREE(wins_ip_addr);
|
||||
SAFE_FREE(src_ip_addr);
|
||||
|
||||
return keystr;
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,7 @@ ADS_STRUCT *ads_init(const char *realm,
|
||||
ads->server.workgroup = workgroup ? strdup(workgroup) : NULL;
|
||||
ads->server.ldap_server = ldap_server? strdup(ldap_server) : NULL;
|
||||
|
||||
/* we need to know if this is a foreign realm to know if we can
|
||||
use lp_ads_server() */
|
||||
/* we need to know if this is a foreign realm */
|
||||
if (realm && *realm && strcasecmp(lp_realm(), realm) != 0) {
|
||||
ads->server.foreign = 1;
|
||||
}
|
||||
|
@ -93,134 +93,76 @@ 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;
|
||||
};
|
||||
/**********************************************************************
|
||||
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
|
||||
**********************************************************************/
|
||||
|
||||
/* 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 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) {
|
||||
if ( c_realm )
|
||||
got_realm = True;
|
||||
|
||||
|
||||
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) {
|
||||
if (!c_realm || !*c_realm)
|
||||
c_realm = lp_workgroup();
|
||||
}
|
||||
if (!c_realm) {
|
||||
return False;
|
||||
}
|
||||
realm = smb_xstrdup(c_realm);
|
||||
|
||||
DEBUG(6,("ads_try_dns: looking for realm '%s'\n", realm));
|
||||
if (ldap_domain2hostlist(realm, &list) != LDAP_SUCCESS) {
|
||||
SAFE_FREE(realm);
|
||||
if (!c_realm)
|
||||
return False;
|
||||
}
|
||||
|
||||
DEBUG(6,("ads_try_dns: ldap realm '%s' host list '%s'\n", realm, list));
|
||||
SAFE_FREE(realm);
|
||||
pstrcpy( realm, c_realm );
|
||||
|
||||
DEBUG(6,("ads_try_dns: looking for %s realm '%s'\n",
|
||||
(got_realm ? "realm" : "domain"), realm));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
count = count_chars(list, ' ') + 1;
|
||||
ip_list = malloc(count * sizeof(struct ldap_ip));
|
||||
if (!ip_list) {
|
||||
return False;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/* if we fail this loop, then giveup since all the IP addresses returned were dead */
|
||||
for ( i=0; i<count; i++ ) {
|
||||
if (ads_try_connect(ads, inet_ntoa(ip_list[i].ip), ip_list[i].port)) {
|
||||
free(ip_list);
|
||||
/* 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
|
||||
* @param ads Pointer to an existing ADS_STRUCT
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1479,7 +1479,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip,
|
||||
|
||||
struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info)
|
||||
{
|
||||
struct in_addr *ip_list;
|
||||
struct ip_service *ip_list;
|
||||
struct cli_state *cli;
|
||||
int i, count;
|
||||
struct in_addr server_ip;
|
||||
@ -1493,7 +1493,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
|
||||
for (i = 0; i < count; i++) {
|
||||
static fstring name;
|
||||
|
||||
if (!name_status_find("*", 0, 0x1d, ip_list[i], name))
|
||||
if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name))
|
||||
continue;
|
||||
|
||||
if (!find_master_ip(name, &server_ip))
|
||||
@ -1502,7 +1502,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user
|
||||
pstrcpy(workgroup, name);
|
||||
|
||||
DEBUG(4, ("found master browser %s, %s\n",
|
||||
name, inet_ntoa(ip_list[i])));
|
||||
name, inet_ntoa(ip_list[i].ip)));
|
||||
|
||||
cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info);
|
||||
|
||||
|
@ -113,7 +113,7 @@ static char* namecache_key(const char *name, int name_type)
|
||||
**/
|
||||
|
||||
BOOL namecache_store(const char *name, int name_type,
|
||||
int num_names, struct in_addr *ip_list)
|
||||
int num_names, struct ip_service *ip_list)
|
||||
{
|
||||
time_t expiry;
|
||||
char *key, *value_string;
|
||||
@ -126,35 +126,18 @@ BOOL namecache_store(const char *name, int name_type,
|
||||
*/
|
||||
if (!gencache_init()) return False;
|
||||
|
||||
if ( DEBUGLEVEL >= 5 ) {
|
||||
DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
|
||||
num_names, num_names == 1 ? "": "es", name, name_type));
|
||||
|
||||
for (i = 0; i < num_names; i++)
|
||||
DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]),
|
||||
i == (num_names - 1) ? "" : ", "));
|
||||
DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip),
|
||||
ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
|
||||
|
||||
DEBUGADD(5, ("\n"));
|
||||
}
|
||||
|
||||
key = namecache_key(name, name_type);
|
||||
|
||||
/*
|
||||
* Cache pdc location or dc lists for only a little while
|
||||
* otherwise if we lock on to a bad DC we can potentially be
|
||||
* out of action for the entire cache timeout time!
|
||||
*/
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* I don't think we need to do this. We are
|
||||
* checking at a higher level for failed DC
|
||||
* connections. JRA.
|
||||
*/
|
||||
|
||||
if (name_type == 0x1b || name_type == 0x1c)
|
||||
expiry = time(NULL) + 10;
|
||||
else
|
||||
expiry = time(NULL) + lp_name_cache_timeout();
|
||||
#endif
|
||||
expiry = time(NULL) + lp_name_cache_timeout();
|
||||
|
||||
/*
|
||||
@ -189,7 +172,7 @@ BOOL namecache_store(const char *name, int name_type,
|
||||
* false if name isn't found in the cache or has expired
|
||||
**/
|
||||
|
||||
BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
|
||||
BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_list,
|
||||
int *num_names)
|
||||
{
|
||||
char *key, *value;
|
||||
@ -225,6 +208,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list,
|
||||
|
||||
SAFE_FREE(key);
|
||||
SAFE_FREE(value);
|
||||
|
||||
return *num_names > 0; /* true only if some ip has been fetched */
|
||||
}
|
||||
|
||||
|
@ -205,6 +205,10 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
|
||||
pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
|
||||
|
||||
/* Store the result in the cache. */
|
||||
/* but don't store an entry for 0x1c names here. Here we have
|
||||
a single host and DOMAIN<0x1c> names should be a list of hosts */
|
||||
|
||||
if ( q_type != 0x1c )
|
||||
namecache_status_store(q_name, q_type, type, to_ip, name);
|
||||
|
||||
result = True;
|
||||
@ -253,6 +257,26 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
|
||||
return max_bits2 - max_bits1;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
compare 2 ldap IPs by nearness to our interfaces - used in qsort
|
||||
*******************************************************************/
|
||||
|
||||
static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
|
||||
{
|
||||
int result;
|
||||
|
||||
if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
|
||||
return result;
|
||||
|
||||
if ( ip1->port > ip2->port )
|
||||
return 1;
|
||||
|
||||
if ( ip1->port < ip2->port )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
sort an IP list so that names that are close to one of our interfaces
|
||||
are at the top. This prevents the problem where a WINS server returns an IP that
|
||||
@ -268,6 +292,51 @@ static void sort_ip_list(struct in_addr *iplist, int count)
|
||||
qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
|
||||
}
|
||||
|
||||
void sort_ip_list2(struct ip_service *iplist, int count)
|
||||
{
|
||||
if (count <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Remove any duplicate address/port pairs in the list
|
||||
*********************************************************************/
|
||||
|
||||
static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
|
||||
|
||||
/* one loop to remove duplicates */
|
||||
for ( i=0; i<count; i++ ) {
|
||||
if ( is_zero_ip(iplist[i].ip) )
|
||||
continue;
|
||||
|
||||
for ( j=i+1; j<count; j++ ) {
|
||||
if ( ip_service_equal(iplist[i], iplist[j]) )
|
||||
zero_ip(&iplist[j].ip);
|
||||
}
|
||||
}
|
||||
|
||||
/* one loop to clean up any holes we left */
|
||||
/* first ip should never be a zero_ip() */
|
||||
for (i = 0; i<count; ) {
|
||||
if ( is_zero_ip(iplist[i].ip) ) {
|
||||
if (i != count-1 )
|
||||
memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
|
||||
count--;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Do a netbios name query to find someones IP.
|
||||
Returns an array of IP addresses or NULL if none.
|
||||
@ -567,23 +636,49 @@ void endlmhosts(XFILE *fp)
|
||||
x_fclose(fp);
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
convert an array if struct in_addrs to struct ip_service
|
||||
return False on failure. Port is set to PORT_NONE;
|
||||
*********************************************************/
|
||||
|
||||
static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( count==0 || !ip_list )
|
||||
return False;
|
||||
|
||||
/* copy the ip address; port will be PORT_NONE */
|
||||
if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) {
|
||||
DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
|
||||
return False;
|
||||
}
|
||||
|
||||
for ( i=0; i<count; i++ ) {
|
||||
(*return_iplist)[i].ip = ip_list[i];
|
||||
(*return_iplist)[i].port = PORT_NONE;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
/********************************************************
|
||||
Resolve via "bcast" method.
|
||||
*********************************************************/
|
||||
|
||||
BOOL name_resolve_bcast(const char *name, int name_type,
|
||||
struct in_addr **return_ip_list, int *return_count)
|
||||
struct ip_service **return_iplist, int *return_count)
|
||||
{
|
||||
int sock, i;
|
||||
int num_interfaces = iface_count();
|
||||
struct in_addr *ip_list;
|
||||
BOOL ret;
|
||||
|
||||
if (lp_disable_netbios()) {
|
||||
DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
|
||||
return False;
|
||||
}
|
||||
|
||||
*return_ip_list = NULL;
|
||||
*return_iplist = NULL;
|
||||
*return_count = 0;
|
||||
|
||||
/*
|
||||
@ -607,16 +702,25 @@ BOOL name_resolve_bcast(const char *name, int name_type,
|
||||
int flags;
|
||||
/* Done this way to fix compiler error on IRIX 5.x */
|
||||
sendto_ip = *iface_n_bcast(i);
|
||||
*return_ip_list = name_query(sock, name, name_type, True,
|
||||
ip_list = name_query(sock, name, name_type, True,
|
||||
True, sendto_ip, return_count, &flags, NULL);
|
||||
if(*return_ip_list != NULL) {
|
||||
close(sock);
|
||||
return True;
|
||||
}
|
||||
if( ip_list )
|
||||
goto success;
|
||||
}
|
||||
|
||||
/* failed - no response */
|
||||
|
||||
close(sock);
|
||||
return False;
|
||||
|
||||
success:
|
||||
ret = True;
|
||||
if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
|
||||
ret = False;
|
||||
|
||||
SAFE_FREE( ip_list );
|
||||
close(sock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
@ -624,11 +728,12 @@ BOOL name_resolve_bcast(const char *name, int name_type,
|
||||
*********************************************************/
|
||||
|
||||
BOOL resolve_wins(const char *name, int name_type,
|
||||
struct in_addr **return_iplist, int *return_count)
|
||||
struct ip_service **return_iplist, int *return_count)
|
||||
{
|
||||
int sock, t, i;
|
||||
char **wins_tags;
|
||||
struct in_addr src_ip;
|
||||
struct in_addr src_ip, *ip_list = NULL;
|
||||
BOOL ret;
|
||||
|
||||
if (lp_disable_netbios()) {
|
||||
DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
|
||||
@ -684,12 +789,12 @@ BOOL resolve_wins(const char *name, int name_type,
|
||||
continue;
|
||||
}
|
||||
|
||||
*return_iplist = name_query(sock,name,name_type, False,
|
||||
ip_list = name_query(sock,name,name_type, False,
|
||||
True, wins_ip, return_count, &flags,
|
||||
&timed_out);
|
||||
if (*return_iplist != NULL) {
|
||||
if ( !ip_list )
|
||||
goto success;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
|
||||
if (timed_out) {
|
||||
@ -707,9 +812,15 @@ BOOL resolve_wins(const char *name, int name_type,
|
||||
return False;
|
||||
|
||||
success:
|
||||
ret = True;
|
||||
if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
|
||||
ret = False;
|
||||
|
||||
SAFE_FREE( ip_list );
|
||||
wins_srv_tags_free(wins_tags);
|
||||
close(sock);
|
||||
return True;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
@ -717,7 +828,7 @@ success:
|
||||
*********************************************************/
|
||||
|
||||
static BOOL resolve_lmhosts(const char *name, int name_type,
|
||||
struct in_addr **return_iplist, int *return_count)
|
||||
struct ip_service **return_iplist, int *return_count)
|
||||
{
|
||||
/*
|
||||
* "lmhosts" means parse the local lmhosts file.
|
||||
@ -740,12 +851,12 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
|
||||
((name_type2 == -1) || (name_type == name_type2))
|
||||
) {
|
||||
endlmhosts(fp);
|
||||
*return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
|
||||
if(*return_iplist == NULL) {
|
||||
if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
|
||||
DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
**return_iplist = return_ip;
|
||||
(*return_iplist)[0].ip = return_ip;
|
||||
(*return_iplist)[0].port = PORT_NONE;
|
||||
*return_count = 1;
|
||||
return True;
|
||||
}
|
||||
@ -760,14 +871,68 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
|
||||
Resolve via "hosts" method.
|
||||
*********************************************************/
|
||||
|
||||
static BOOL resolve_hosts(const char *name,
|
||||
struct in_addr **return_iplist, int *return_count)
|
||||
static BOOL resolve_hosts(const char *name, int name_type,
|
||||
struct ip_service **return_iplist, int *return_count)
|
||||
{
|
||||
/*
|
||||
* "host" means do a localhost, or dns lookup.
|
||||
*/
|
||||
struct hostent *hp;
|
||||
|
||||
#ifdef HAVE_ADS
|
||||
if ( name_type == 0x1c ) {
|
||||
int count, i = 0;
|
||||
char *list = NULL;
|
||||
const char *ptr;
|
||||
pstring tok;
|
||||
|
||||
/* try to lookup the _ldap._tcp.<domain> if we are using ADS */
|
||||
if ( lp_security() != SEC_ADS )
|
||||
return False;
|
||||
|
||||
DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
|
||||
name));
|
||||
|
||||
if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS)
|
||||
return False;
|
||||
|
||||
count = count_chars(list, ' ') + 1;
|
||||
if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) {
|
||||
DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count ));
|
||||
return False;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
(*return_iplist)[i].ip = *interpret_addr2(tok);
|
||||
(*return_iplist)[i].port = port;
|
||||
|
||||
/* make sure it is a valid IP. I considered checking the negative
|
||||
connection cache, but this is the wrong place for it. Maybe only
|
||||
as a hac. After think about it, if all of the IP addresses retuend
|
||||
from DNS are dead, what hope does a netbios name lookup have?
|
||||
The standard reason for falling back to netbios lookups is that
|
||||
our DNS server doesn't know anything about the DC's -- jerry */
|
||||
|
||||
if ( is_zero_ip((*return_iplist)[i].ip) )
|
||||
continue;
|
||||
|
||||
i++;
|
||||
}
|
||||
SAFE_FREE(list);
|
||||
|
||||
*return_count = i;
|
||||
|
||||
return True;
|
||||
}
|
||||
#endif /* HAVE_ADS */
|
||||
|
||||
*return_iplist = NULL;
|
||||
*return_count = 0;
|
||||
|
||||
@ -776,27 +941,33 @@ static BOOL resolve_hosts(const char *name,
|
||||
if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
|
||||
struct in_addr return_ip;
|
||||
putip((char *)&return_ip,(char *)hp->h_addr);
|
||||
*return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
|
||||
*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service));
|
||||
if(*return_iplist == NULL) {
|
||||
DEBUG(3,("resolve_hosts: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
**return_iplist = return_ip;
|
||||
(*return_iplist)->ip = return_ip;
|
||||
(*return_iplist)->port = PORT_NONE;
|
||||
*return_count = 1;
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
/*******************************************************************
|
||||
Internal interface to resolve a name into an IP address.
|
||||
Use this function if the string is either an IP address, DNS
|
||||
or host name or NetBIOS name. This uses the name switch in the
|
||||
smb.conf to determine the order of name resolution.
|
||||
*********************************************************/
|
||||
|
||||
Added support for ip addr/port to support ADS ldap servers.
|
||||
the only place we currently care about the port is in the
|
||||
resolve_hosts() when looking up DC's via SRV RR entries in DNS
|
||||
**********************************************************************/
|
||||
|
||||
static BOOL internal_resolve_name(const char *name, int name_type,
|
||||
struct in_addr **return_iplist, int *return_count)
|
||||
struct ip_service **return_iplist,
|
||||
int *return_count, const char *resolve_order)
|
||||
{
|
||||
pstring name_resolve_list;
|
||||
fstring tok;
|
||||
@ -805,7 +976,6 @@ static BOOL internal_resolve_name(const char *name, int name_type,
|
||||
BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
|
||||
BOOL is_address = is_ipaddress(name);
|
||||
BOOL result = False;
|
||||
struct in_addr *nodupes_iplist;
|
||||
int i;
|
||||
|
||||
*return_iplist = NULL;
|
||||
@ -814,42 +984,56 @@ static BOOL internal_resolve_name(const char *name, int name_type,
|
||||
DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type));
|
||||
|
||||
if (allzeros || allones || is_address) {
|
||||
*return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
|
||||
if(*return_iplist == NULL) {
|
||||
DEBUG(3,("internal_resolve_name: malloc fail !\n"));
|
||||
|
||||
if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) {
|
||||
DEBUG(0,("internal_resolve_name: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
|
||||
if(is_address) {
|
||||
/* ignore the port here */
|
||||
(*return_iplist)->port = PORT_NONE;
|
||||
|
||||
/* if it's in the form of an IP address then get the lib to interpret it */
|
||||
if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){
|
||||
if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
|
||||
DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
|
||||
return False;
|
||||
}
|
||||
} else {
|
||||
(*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
|
||||
(*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
|
||||
*return_count = 1;
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Check netbios name cache */
|
||||
/* Check name cache */
|
||||
|
||||
if (namecache_fetch(name, name_type, return_iplist, return_count)) {
|
||||
|
||||
/* This could be a negative response */
|
||||
|
||||
return (*return_count > 0);
|
||||
}
|
||||
|
||||
/* set the name resolution order */
|
||||
|
||||
if ( !resolve_order )
|
||||
pstrcpy(name_resolve_list, lp_name_resolve_order());
|
||||
ptr = name_resolve_list;
|
||||
if (!ptr || !*ptr)
|
||||
else
|
||||
pstrcpy(name_resolve_list, resolve_order);
|
||||
|
||||
if ( !name_resolve_list[0] )
|
||||
ptr = "host";
|
||||
else
|
||||
ptr = name_resolve_list;
|
||||
|
||||
/* iterate through the name resolution backends */
|
||||
|
||||
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
|
||||
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
|
||||
if (name_type == 0x20) {
|
||||
if (resolve_hosts(name, return_iplist, return_count)) {
|
||||
/* deal with 0x20 & 0x1c names here. The latter will result
|
||||
in a SRV record lookup for _ldap._tcp.<domain> if we are using
|
||||
'security = ads' */
|
||||
if ( name_type==0x20 || name_type == 0x1c ) {
|
||||
if (resolve_hosts(name, name_type, return_iplist, return_count)) {
|
||||
result = True;
|
||||
goto done;
|
||||
}
|
||||
@ -890,57 +1074,30 @@ static BOOL internal_resolve_name(const char *name, int name_type,
|
||||
controllers including the PDC in iplist[1..n]. Iterating over
|
||||
the iplist when the PDC is down will cause two sets of timeouts. */
|
||||
|
||||
if (*return_count && (nodupes_iplist = (struct in_addr *)
|
||||
malloc(sizeof(struct in_addr) * (*return_count)))) {
|
||||
int nodupes_count = 0;
|
||||
|
||||
/* Iterate over return_iplist looking for duplicates */
|
||||
|
||||
for (i = 0; i < *return_count; i++) {
|
||||
BOOL is_dupe = False;
|
||||
int j;
|
||||
|
||||
for (j = i + 1; j < *return_count; j++) {
|
||||
if (ip_equal((*return_iplist)[i],
|
||||
(*return_iplist)[j])) {
|
||||
is_dupe = True;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_dupe) {
|
||||
|
||||
/* This one not a duplicate */
|
||||
|
||||
nodupes_iplist[nodupes_count] = (*return_iplist)[i];
|
||||
nodupes_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Switcheroo with original list */
|
||||
|
||||
free(*return_iplist);
|
||||
|
||||
*return_iplist = nodupes_iplist;
|
||||
*return_count = nodupes_count;
|
||||
if ( *return_count ) {
|
||||
*return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
|
||||
}
|
||||
|
||||
/* Save in name cache */
|
||||
if ( DEBUGLEVEL >= 100 ) {
|
||||
for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
|
||||
DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name,
|
||||
name_type, inet_ntoa((*return_iplist)[i])));
|
||||
DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
|
||||
name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
|
||||
}
|
||||
|
||||
namecache_store(name, name_type, *return_count, *return_iplist);
|
||||
|
||||
/* Display some debugging info */
|
||||
|
||||
if ( DEBUGLEVEL >= 10 ) {
|
||||
DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
|
||||
*return_count));
|
||||
|
||||
for (i = 0; i < *return_count; i++)
|
||||
DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i])));
|
||||
DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
|
||||
|
||||
DEBUG(10, ("\n"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -954,7 +1111,7 @@ static BOOL internal_resolve_name(const char *name, int name_type,
|
||||
|
||||
BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
|
||||
{
|
||||
struct in_addr *ip_list = NULL;
|
||||
struct ip_service *ip_list = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (is_ipaddress(name)) {
|
||||
@ -962,20 +1119,23 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
|
||||
return True;
|
||||
}
|
||||
|
||||
if (internal_resolve_name(name, name_type, &ip_list, &count)) {
|
||||
if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) {
|
||||
int i;
|
||||
|
||||
/* only return valid addresses for TCP connections */
|
||||
for (i=0; i<count; i++) {
|
||||
char *ip_str = inet_ntoa(ip_list[i]);
|
||||
char *ip_str = inet_ntoa(ip_list[i].ip);
|
||||
if (ip_str &&
|
||||
strcmp(ip_str, "255.255.255.255") != 0 &&
|
||||
strcmp(ip_str, "0.0.0.0") != 0) {
|
||||
*return_ip = ip_list[i];
|
||||
strcmp(ip_str, "0.0.0.0") != 0)
|
||||
{
|
||||
*return_ip = ip_list[i].ip;
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
return False;
|
||||
}
|
||||
@ -986,7 +1146,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
|
||||
|
||||
BOOL find_master_ip(const char *group, struct in_addr *master_ip)
|
||||
{
|
||||
struct in_addr *ip_list = NULL;
|
||||
struct ip_service *ip_list = NULL;
|
||||
int count = 0;
|
||||
|
||||
if (lp_disable_netbios()) {
|
||||
@ -994,13 +1154,13 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
|
||||
return False;
|
||||
}
|
||||
|
||||
if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
|
||||
*master_ip = ip_list[0];
|
||||
if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) {
|
||||
*master_ip = ip_list[0].ip;
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
|
||||
*master_ip = ip_list[0];
|
||||
if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) {
|
||||
*master_ip = ip_list[0].ip;
|
||||
SAFE_FREE(ip_list);
|
||||
return True;
|
||||
}
|
||||
@ -1009,217 +1169,6 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip)
|
||||
return False;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
Lookup a DC name given a Domain name and IP address.
|
||||
*********************************************************/
|
||||
|
||||
BOOL lookup_dc_name(const char *srcname, const char *domain,
|
||||
struct in_addr *dc_ip, char *ret_name)
|
||||
{
|
||||
#if !defined(I_HATE_WINDOWS_REPLY_CODE)
|
||||
fstring dc_name;
|
||||
BOOL ret;
|
||||
|
||||
if (lp_disable_netbios()) {
|
||||
DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Due to the fact win WinNT *sucks* we must do a node status
|
||||
* query here... JRA.
|
||||
*/
|
||||
|
||||
*dc_name = '\0';
|
||||
|
||||
ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name);
|
||||
|
||||
if(ret && *dc_name) {
|
||||
fstrcpy(ret_name, dc_name);
|
||||
return True;
|
||||
}
|
||||
|
||||
return False;
|
||||
|
||||
#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
|
||||
|
||||
JRA - This code is broken with BDC rollover - we need to do a full
|
||||
NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
|
||||
|
||||
int retries = 3;
|
||||
int retry_time = 2000;
|
||||
struct timeval tval;
|
||||
struct packet_struct p;
|
||||
struct dgram_packet *dgram = &p.packet.dgram;
|
||||
char *ptr,*p2;
|
||||
char tmp[4];
|
||||
int len;
|
||||
struct sockaddr_in sock_name;
|
||||
int sock_len = sizeof(sock_name);
|
||||
const char *mailslot = NET_LOGON_MAILSLOT;
|
||||
char *mailslot_name;
|
||||
char buffer[1024];
|
||||
char *bufp;
|
||||
int dgm_id = generate_trn_id();
|
||||
int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
|
||||
|
||||
if(sock == -1)
|
||||
return False;
|
||||
|
||||
/* Find out the transient UDP port we have been allocated. */
|
||||
if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
|
||||
DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
|
||||
strerror(errno)));
|
||||
close(sock);
|
||||
return False;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the request data.
|
||||
*/
|
||||
|
||||
memset(buffer,'\0',sizeof(buffer));
|
||||
bufp = buffer;
|
||||
SSVAL(bufp,0,QUERYFORPDC);
|
||||
bufp += 2;
|
||||
fstrcpy(bufp,srcname);
|
||||
bufp += (strlen(bufp) + 1);
|
||||
slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
|
||||
mailslot_name = bufp;
|
||||
bufp += (strlen(bufp) + 1);
|
||||
bufp = ALIGN2(bufp, buffer);
|
||||
bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE);
|
||||
|
||||
SIVAL(bufp,0,1);
|
||||
SSVAL(bufp,4,0xFFFF);
|
||||
SSVAL(bufp,6,0xFFFF);
|
||||
bufp += 8;
|
||||
len = PTR_DIFF(bufp,buffer);
|
||||
|
||||
memset((char *)&p,'\0',sizeof(p));
|
||||
|
||||
/* DIRECT GROUP or UNIQUE datagram. */
|
||||
dgram->header.msg_type = 0x10;
|
||||
dgram->header.flags.node_type = M_NODE;
|
||||
dgram->header.flags.first = True;
|
||||
dgram->header.flags.more = False;
|
||||
dgram->header.dgm_id = dgm_id;
|
||||
dgram->header.source_ip = *iface_ip(*pdc_ip);
|
||||
dgram->header.source_port = ntohs(sock_name.sin_port);
|
||||
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
|
||||
dgram->header.packet_offset = 0;
|
||||
|
||||
make_nmb_name(&dgram->source_name,srcname,0);
|
||||
make_nmb_name(&dgram->dest_name,domain,0x1C);
|
||||
|
||||
ptr = &dgram->data[0];
|
||||
|
||||
/* Setup the smb part. */
|
||||
ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
|
||||
memcpy(tmp,ptr,4);
|
||||
set_message(ptr,17,17 + len,True);
|
||||
memcpy(ptr,tmp,4);
|
||||
|
||||
CVAL(ptr,smb_com) = SMBtrans;
|
||||
SSVAL(ptr,smb_vwv1,len);
|
||||
SSVAL(ptr,smb_vwv11,len);
|
||||
SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
|
||||
SSVAL(ptr,smb_vwv13,3);
|
||||
SSVAL(ptr,smb_vwv14,1);
|
||||
SSVAL(ptr,smb_vwv15,1);
|
||||
SSVAL(ptr,smb_vwv16,2);
|
||||
p2 = smb_buf(ptr);
|
||||
pstrcpy(p2,mailslot);
|
||||
p2 = skip_string(p2,1);
|
||||
|
||||
memcpy(p2,buffer,len);
|
||||
p2 += len;
|
||||
|
||||
dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
|
||||
|
||||
p.ip = *pdc_ip;
|
||||
p.port = DGRAM_PORT;
|
||||
p.fd = sock;
|
||||
p.timestamp = time(NULL);
|
||||
p.packet_type = DGRAM_PACKET;
|
||||
|
||||
GetTimeOfDay(&tval);
|
||||
|
||||
if (!send_packet(&p)) {
|
||||
DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
|
||||
close(sock);
|
||||
return False;
|
||||
}
|
||||
|
||||
retries--;
|
||||
|
||||
while (1) {
|
||||
struct timeval tval2;
|
||||
struct packet_struct *p_ret;
|
||||
|
||||
GetTimeOfDay(&tval2);
|
||||
if (TvalDiff(&tval,&tval2) > retry_time) {
|
||||
if (!retries)
|
||||
break;
|
||||
if (!send_packet(&p)) {
|
||||
DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
|
||||
close(sock);
|
||||
return False;
|
||||
}
|
||||
GetTimeOfDay(&tval);
|
||||
retries--;
|
||||
}
|
||||
|
||||
if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
|
||||
struct dgram_packet *dgram2 = &p_ret->packet.dgram;
|
||||
char *buf;
|
||||
char *buf2;
|
||||
|
||||
buf = &dgram2->data[0];
|
||||
buf -= 4;
|
||||
|
||||
if (CVAL(buf,smb_com) != SMBtrans) {
|
||||
DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
|
||||
CVAL(buf,smb_com), (unsigned int)SMBtrans ));
|
||||
free_packet(p_ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
len = SVAL(buf,smb_vwv11);
|
||||
buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
|
||||
|
||||
if (len <= 0) {
|
||||
DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
|
||||
free_packet(p_ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
|
||||
nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
|
||||
inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
|
||||
|
||||
if(SVAL(buf2,0) != QUERYFORPDC_R) {
|
||||
DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
|
||||
(unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
|
||||
free_packet(p_ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
buf2 += 2;
|
||||
/* Note this is safe as it is a bounded strcpy. */
|
||||
fstrcpy(ret_name, buf2);
|
||||
ret_name[sizeof(fstring)-1] = '\0';
|
||||
close(sock);
|
||||
free_packet(p_ret);
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return False;
|
||||
#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
Get the IP address list of the primary domain controller
|
||||
for a domain.
|
||||
@ -1227,13 +1176,12 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
|
||||
|
||||
BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
|
||||
{
|
||||
struct in_addr *ip_list;
|
||||
struct ip_service *ip_list;
|
||||
int count;
|
||||
int i = 0;
|
||||
|
||||
/* Look up #1B name */
|
||||
|
||||
if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
|
||||
if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order()))
|
||||
return False;
|
||||
|
||||
/* if we get more than 1 IP back we have to assume it is a
|
||||
@ -1241,54 +1189,68 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
|
||||
|
||||
if ( count > 1 ) {
|
||||
DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
|
||||
|
||||
/* look for a local net */
|
||||
for ( i=0; i<count; i++ ) {
|
||||
if ( is_local_net( ip_list[i] ) )
|
||||
break;
|
||||
sort_ip_list2( ip_list, count );
|
||||
}
|
||||
|
||||
/* if we hit then end then just grab the first
|
||||
one from the list */
|
||||
|
||||
if ( i == count )
|
||||
i = 0;
|
||||
}
|
||||
|
||||
*ip = ip_list[i];
|
||||
*ip = ip_list[0].ip;
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
small wrapper function to get the DC list and sort it if neccessary
|
||||
*********************************************************************/
|
||||
BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL dns_only )
|
||||
{
|
||||
BOOL ordered;
|
||||
|
||||
DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n",
|
||||
(dns_only ? "hosts" : lp_name_resolve_order())));
|
||||
|
||||
if ( !get_dc_list(domain, ip_list, count, dns_only, &ordered) )
|
||||
return False;
|
||||
|
||||
/* only sort if we don't already have an ordered list */
|
||||
if ( !ordered )
|
||||
sort_ip_list2( *ip_list, *count );
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/********************************************************
|
||||
Get the IP address list of the domain controllers for
|
||||
a domain.
|
||||
*********************************************************/
|
||||
|
||||
BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered)
|
||||
BOOL get_dc_list(const char *domain, struct ip_service **ip_list,
|
||||
int *count, BOOL dns_only, int *ordered)
|
||||
{
|
||||
/* defined the name resolve order to internal_name_resolve()
|
||||
only used for looking up 0x1c names */
|
||||
const char *resolve_oder = (dns_only ? "hosts" : lp_name_resolve_order());
|
||||
|
||||
*ordered = False;
|
||||
|
||||
/* If it's our domain then use the 'password server' parameter. */
|
||||
|
||||
if (strequal(domain, lp_workgroup())) {
|
||||
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 in_addr *return_iplist = NULL;
|
||||
struct in_addr *auto_ip_list = NULL;
|
||||
struct ip_service *return_iplist = NULL;
|
||||
struct ip_service *auto_ip_list = NULL;
|
||||
BOOL done_auto_lookup = False;
|
||||
int auto_count = 0;
|
||||
|
||||
|
||||
if (!*pserver)
|
||||
return internal_resolve_name(
|
||||
domain, 0x1C, ip_list, count);
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
|
||||
|
||||
p = pserver;
|
||||
|
||||
@ -1301,7 +1263,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
|
||||
|
||||
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
|
||||
if (strequal(name, "*")) {
|
||||
if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) )
|
||||
if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_oder) )
|
||||
num_addresses += auto_count;
|
||||
done_auto_lookup = True;
|
||||
DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
|
||||
@ -1314,11 +1276,11 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
|
||||
just return the list of DC's */
|
||||
|
||||
if ( (num_addresses == 0) && !done_auto_lookup )
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count);
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder);
|
||||
|
||||
return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr));
|
||||
|
||||
if (return_iplist == NULL) {
|
||||
if ( (return_iplist = (struct ip_service *)
|
||||
malloc(num_addresses * sizeof(struct ip_service))) == NULL )
|
||||
{
|
||||
DEBUG(3,("get_dc_list: malloc fail !\n"));
|
||||
return False;
|
||||
}
|
||||
@ -1334,57 +1296,49 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
|
||||
/* 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];
|
||||
for ( j=0; j<auto_count; j++ ) {
|
||||
return_iplist[local_count].ip = auto_ip_list[j].ip;
|
||||
return_iplist[local_count].port = auto_ip_list[j].port;
|
||||
local_count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* explicit lookup; resolve_name() will handle names & IP addresses */
|
||||
|
||||
if ( resolve_name( name, &name_ip, 0x20) ) {
|
||||
return_iplist[local_count++] = name_ip;
|
||||
*ordered = True;
|
||||
/* 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 ) ) {
|
||||
return_iplist[local_count].ip = name_ip;
|
||||
return_iplist[local_count].port = port;
|
||||
local_count++;
|
||||
*ordered = True;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE(auto_ip_list);
|
||||
|
||||
/* need to remove duplicates in the list if we have
|
||||
any explicit password servers */
|
||||
/* need to remove duplicates in the list if we have any
|
||||
explicit password servers */
|
||||
|
||||
if ( *ordered ) {
|
||||
/* 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 should never be a zero_ip() */
|
||||
for (i = 0; i<local_count; ) {
|
||||
if ( is_zero_ip(return_iplist[i]) ) {
|
||||
if (i != local_count-1 )
|
||||
memmove(&return_iplist[i], &return_iplist[i+1],
|
||||
(local_count - i - 1)*sizeof(return_iplist[i]));
|
||||
local_count--;
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
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 ", inet_ntoa(return_iplist[i])));
|
||||
DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
|
||||
DEBUGADD(4,("\n"));
|
||||
}
|
||||
|
||||
@ -1394,5 +1348,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *
|
||||
return (*count != 0);
|
||||
}
|
||||
|
||||
return internal_resolve_name(domain, 0x1C, ip_list, count);
|
||||
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_oder);
|
||||
}
|
||||
|
@ -24,137 +24,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
|
||||
#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */
|
||||
|
||||
struct failed_connection_cache {
|
||||
fstring domain_name;
|
||||
fstring controller;
|
||||
time_t lookup_time;
|
||||
NTSTATUS nt_status;
|
||||
struct failed_connection_cache *prev, *next;
|
||||
};
|
||||
|
||||
static struct failed_connection_cache *failed_connection_cache;
|
||||
|
||||
/**********************************************************************
|
||||
Check for a previously failed connection
|
||||
**********************************************************************/
|
||||
|
||||
static NTSTATUS check_negative_conn_cache( const char *domain, const char *server )
|
||||
{
|
||||
struct failed_connection_cache *fcc;
|
||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
/* can't check if we don't have strings */
|
||||
|
||||
if ( !domain || !server )
|
||||
return NT_STATUS_OK;
|
||||
|
||||
for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
|
||||
|
||||
/*
|
||||
* we have a match IFF the domain and server name matches
|
||||
* (a) the domain matches,
|
||||
* (b) the IP address matches (if we have one)
|
||||
* (c) the server name (if specified) matches
|
||||
*/
|
||||
|
||||
if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) )
|
||||
continue; /* no match; check the next entry */
|
||||
|
||||
/* we have a match so see if it is still current */
|
||||
|
||||
if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT)
|
||||
{
|
||||
/* Cache entry has expired, delete it */
|
||||
|
||||
DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n",
|
||||
domain, server ));
|
||||
|
||||
DLIST_REMOVE(failed_connection_cache, fcc);
|
||||
SAFE_FREE(fcc);
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/* The timeout hasn't expired yet so return false */
|
||||
|
||||
DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n",
|
||||
domain, server ));
|
||||
|
||||
result = fcc->nt_status;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* end of function means no cache entry */
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Add an entry to the failed conneciton cache
|
||||
**********************************************************************/
|
||||
|
||||
void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result)
|
||||
{
|
||||
struct failed_connection_cache *fcc;
|
||||
|
||||
SMB_ASSERT(!NT_STATUS_IS_OK(result));
|
||||
|
||||
/* Check we already aren't in the cache. We always have to have
|
||||
a domain, but maybe not a specific DC name. */
|
||||
|
||||
for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
|
||||
if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) )
|
||||
{
|
||||
DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
|
||||
domain, server ));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create negative lookup cache entry for this domain and controller */
|
||||
|
||||
if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) )
|
||||
{
|
||||
DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(fcc);
|
||||
|
||||
fstrcpy( fcc->domain_name, domain );
|
||||
fstrcpy( fcc->controller, server );
|
||||
fcc->lookup_time = time(NULL);
|
||||
fcc->nt_status = result;
|
||||
|
||||
DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
|
||||
domain, server ));
|
||||
|
||||
DLIST_ADD(failed_connection_cache, fcc);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
|
||||
void flush_negative_conn_cache( void )
|
||||
{
|
||||
struct failed_connection_cache *fcc;
|
||||
|
||||
fcc = failed_connection_cache;
|
||||
|
||||
while (fcc) {
|
||||
struct failed_connection_cache *fcc_next;
|
||||
|
||||
fcc_next = fcc->next;
|
||||
DLIST_REMOVE(failed_connection_cache, fcc);
|
||||
free(fcc);
|
||||
|
||||
fcc = fcc_next;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function to return the name of a DC. The name is guaranteed to be
|
||||
valid since we have already done a name_status_find on it
|
||||
@ -162,9 +31,9 @@ void flush_negative_conn_cache( void )
|
||||
|
||||
BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
|
||||
{
|
||||
struct in_addr *ip_list = NULL, dc_ip, exclude_ip;
|
||||
struct ip_service *ip_list = NULL;
|
||||
struct in_addr dc_ip, exclude_ip;
|
||||
int count, i;
|
||||
BOOL list_ordered;
|
||||
BOOL use_pdc_only;
|
||||
NTSTATUS result;
|
||||
|
||||
@ -181,7 +50,7 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
|
||||
/* 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, 0x1c, 0x20, dc_ip, srv_name) ) {
|
||||
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;
|
||||
@ -192,7 +61,7 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
|
||||
|
||||
/* get a list of all domain controllers */
|
||||
|
||||
if (!get_dc_list( domain, &ip_list, &count, &list_ordered) ) {
|
||||
if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
|
||||
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
@ -201,25 +70,19 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out)
|
||||
|
||||
if ( use_pdc_only ) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (ip_equal( exclude_ip, ip_list[i]))
|
||||
zero_ip(&ip_list[i]);
|
||||
if (ip_equal( exclude_ip, ip_list[i].ip))
|
||||
zero_ip(&ip_list[i].ip);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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]))
|
||||
if (is_zero_ip(ip_list[i].ip))
|
||||
continue;
|
||||
|
||||
if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) {
|
||||
if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) {
|
||||
result = check_negative_conn_cache( domain, srv_name );
|
||||
if ( NT_STATUS_IS_OK(result) ) {
|
||||
dc_ip = ip_list[i];
|
||||
dc_ip = ip_list[i].ip;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
@ -76,22 +76,10 @@ struct winbindd_cm_conn {
|
||||
|
||||
static struct winbindd_cm_conn *cm_conns = NULL;
|
||||
|
||||
/* Get a domain controller name. Cache positive and negative lookups so we
|
||||
don't go to the network too often when something is badly broken. */
|
||||
|
||||
#define GET_DC_NAME_CACHE_TIMEOUT 30 /* Seconds between dc lookups */
|
||||
|
||||
struct get_dc_name_cache {
|
||||
fstring domain_name;
|
||||
fstring srv_name;
|
||||
time_t lookup_time;
|
||||
struct get_dc_name_cache *prev, *next;
|
||||
};
|
||||
|
||||
/*
|
||||
find the DC for a domain using methods appropriate for a ADS domain
|
||||
*/
|
||||
static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
|
||||
static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name)
|
||||
{
|
||||
ADS_STRUCT *ads;
|
||||
const char *realm = domain;
|
||||
@ -123,7 +111,7 @@ static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
|
||||
*dc_ip = ads->ldap_ip;
|
||||
ads_destroy(&ads);
|
||||
|
||||
DEBUG(4,("cm_ads_find_dc: using server='%s' IP=%s\n",
|
||||
DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n",
|
||||
srv_name, inet_ntoa(*dc_ip)));
|
||||
|
||||
return True;
|
||||
@ -143,7 +131,7 @@ static BOOL cm_get_dc_name(const char *domain, fstring srv_name,
|
||||
|
||||
ret = False;
|
||||
if (lp_security() == SEC_ADS)
|
||||
ret = cm_ads_find_dc(domain, &dc_ip, srv_name);
|
||||
ret = ads_dc_name(domain, &dc_ip, srv_name);
|
||||
|
||||
if (!ret) {
|
||||
/* fall back on rpc methods if the ADS methods fail */
|
||||
|
@ -715,7 +715,7 @@ static LDAP *ldap_open_with_timeout(const char *server, int port, unsigned int t
|
||||
return ldp;
|
||||
}
|
||||
|
||||
static int get_ldap_seq(const char *server, uint32 *seq)
|
||||
static int get_ldap_seq(const char *server, int port, uint32 *seq)
|
||||
{
|
||||
int ret = -1;
|
||||
struct timeval to;
|
||||
@ -731,7 +731,7 @@ static int get_ldap_seq(const char *server, uint32 *seq)
|
||||
* doesn't seem to apply to doing an open as well. JRA.
|
||||
*/
|
||||
|
||||
if ((ldp = ldap_open_with_timeout(server, LDAP_PORT, 10)) == NULL)
|
||||
if ((ldp = ldap_open_with_timeout(server, port, 10)) == NULL)
|
||||
return -1;
|
||||
|
||||
/* Timeout if no response within 20 seconds. */
|
||||
@ -770,36 +770,39 @@ static int get_ldap_seq(const char *server, uint32 *seq)
|
||||
int get_ldap_sequence_number( const char* domain, uint32 *seq)
|
||||
{
|
||||
int ret = -1;
|
||||
int i;
|
||||
struct in_addr *ip_list = NULL;
|
||||
int i, port = LDAP_PORT;
|
||||
struct ip_service *ip_list = NULL;
|
||||
int count;
|
||||
BOOL list_ordered;
|
||||
|
||||
if ( !get_dc_list( domain, &ip_list, &count, &list_ordered ) ) {
|
||||
if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) {
|
||||
DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
|
||||
return False;
|
||||
}
|
||||
|
||||
/* sort the list so we can pick a close server */
|
||||
|
||||
if (!list_ordered && (count > 1) ) {
|
||||
qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
|
||||
}
|
||||
|
||||
/* Finally return first DC that we can contact */
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (is_zero_ip(ip_list[i]))
|
||||
fstring ipstr;
|
||||
|
||||
/* since the is an LDAP lookup, default to the LDAP_PORT is not set */
|
||||
port = (ip_list[i].port!= PORT_NONE) ? ip_list[i].port : LDAP_PORT;
|
||||
|
||||
fstrcpy( ipstr, inet_ntoa(ip_list[i].ip) );
|
||||
|
||||
if (is_zero_ip(ip_list[i].ip))
|
||||
continue;
|
||||
|
||||
if ( (ret = get_ldap_seq( inet_ntoa(ip_list[i]), seq)) == 0 )
|
||||
if ( (ret = get_ldap_seq( ipstr, port, seq)) == 0 )
|
||||
goto done;
|
||||
|
||||
/* add to failed connection cache */
|
||||
add_failed_connection_entry( domain, ipstr, NT_STATUS_UNSUCCESSFUL );
|
||||
}
|
||||
|
||||
done:
|
||||
if ( ret == 0 ) {
|
||||
DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s)\n",
|
||||
domain, inet_ntoa(ip_list[i])));
|
||||
DEBUG(3, ("get_ldap_sequence_number: Retrieved sequence number for Domain (%s) from DC (%s:%d)\n",
|
||||
domain, inet_ntoa(ip_list[i].ip), port));
|
||||
}
|
||||
|
||||
SAFE_FREE(ip_list);
|
||||
|
@ -112,7 +112,8 @@ static struct node_status *lookup_byaddr_backend(char *addr, int *count)
|
||||
static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
{
|
||||
int fd = -1;
|
||||
struct in_addr *ret = NULL;
|
||||
struct ip_service *address = NULL;
|
||||
struct in_addr *ret;
|
||||
int j, flags = 0;
|
||||
|
||||
if (!initialised) {
|
||||
@ -122,7 +123,13 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
|
||||
*count = 0;
|
||||
|
||||
/* always try with wins first */
|
||||
if (resolve_wins(name,0x20,&ret,count)) {
|
||||
if (resolve_wins(name,0x20,&address,count)) {
|
||||
if ( (ret = (struct in_addr *)malloc(sizeof(struct in_addr))) == NULL ) {
|
||||
free( address );
|
||||
return NULL;
|
||||
}
|
||||
*ret = address[0].ip;
|
||||
free( address );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,6 @@ typedef struct
|
||||
char *szPasswordServer;
|
||||
char *szSocketOptions;
|
||||
char *szRealm;
|
||||
char *szADSserver;
|
||||
char *szUsernameMap;
|
||||
char *szLogonScript;
|
||||
char *szLogonPath;
|
||||
@ -736,7 +735,6 @@ static struct parm_struct parm_table[] = {
|
||||
{"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
|
||||
{"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||
{"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||
{"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||
{"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||
{"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
|
||||
{"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
|
||||
@ -1597,7 +1595,6 @@ FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
|
||||
FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
|
||||
FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
|
||||
FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
|
||||
FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
|
||||
FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
|
||||
FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
|
||||
FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
|
||||
|
@ -304,7 +304,7 @@ static NTSTATUS context_getgrgid(struct pdb_context *context,
|
||||
}
|
||||
|
||||
static NTSTATUS context_getgrnam(struct pdb_context *context,
|
||||
GROUP_MAP *map, char *name)
|
||||
GROUP_MAP *map, const char *name)
|
||||
{
|
||||
NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
|
||||
|
||||
|
@ -252,8 +252,7 @@ BOOL secrets_fetch_trust_account_password(const char *domain, uint8 ret_pwd[16],
|
||||
plaintext = secrets_fetch_machine_password(domain, pass_last_set_time,
|
||||
channel);
|
||||
if (plaintext) {
|
||||
/* we have an ADS password - use that */
|
||||
DEBUG(4,("Using ADS machine password\n"));
|
||||
DEBUG(4,("Using cleartext machine password\n"));
|
||||
E_md4hash(plaintext, ret_pwd);
|
||||
SAFE_FREE(plaintext);
|
||||
return True;
|
||||
|
@ -2601,8 +2601,9 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
|
||||
printer->info_2->sharename);
|
||||
|
||||
/* connect to the ADS server */
|
||||
ads = ads_init(NULL, NULL, lp_ads_server());
|
||||
/* initial ads structure */
|
||||
|
||||
ads = ads_init(NULL, NULL, NULL);
|
||||
if (!ads) {
|
||||
DEBUG(3, ("ads_init() failed\n"));
|
||||
return WERR_SERVER_UNAVAILABLE;
|
||||
@ -2611,6 +2612,8 @@ static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
SAFE_FREE(ads->auth.password);
|
||||
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
|
||||
NULL, NULL);
|
||||
|
||||
/* ads_connect() will find the DC for us */
|
||||
ads_rc = ads_connect(ads);
|
||||
if (!ADS_ERR_OK(ads_rc)) {
|
||||
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
|
||||
@ -2663,7 +2666,7 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
return win_rc;
|
||||
}
|
||||
|
||||
ads = ads_init(NULL, NULL, lp_ads_server());
|
||||
ads = ads_init(NULL, NULL, NULL);
|
||||
if (!ads) {
|
||||
DEBUG(3, ("ads_init() failed\n"));
|
||||
return WERR_SERVER_UNAVAILABLE;
|
||||
@ -2672,6 +2675,8 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
|
||||
SAFE_FREE(ads->auth.password);
|
||||
ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
|
||||
NULL, NULL);
|
||||
|
||||
/* ads_connect() will find the DC for us */
|
||||
ads_rc = ads_connect(ads);
|
||||
if (!ADS_ERR_OK(ads_rc)) {
|
||||
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
|
||||
|
@ -43,7 +43,7 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if ( !lookup_dc_name(global_myname(), domain, &pdc_ip, dc_name) )
|
||||
if ( !name_status_find( domain, 0x1b, 0x20, pdc_ip, dc_name) )
|
||||
goto failed;
|
||||
}
|
||||
/* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
|
||||
|
@ -206,7 +206,7 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
|
||||
if (is_zero_ip(pdc_ip))
|
||||
return False;
|
||||
|
||||
if (!lookup_dc_name(global_myname(), opt_target_workgroup, &pdc_ip, dc_name))
|
||||
if ( !name_status_find(opt_target_workgroup, 0x1b, 0x20, pdc_ip, dc_name) )
|
||||
return False;
|
||||
|
||||
*server_name = strdup(dc_name);
|
||||
@ -248,20 +248,18 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
|
||||
}
|
||||
|
||||
|
||||
BOOL net_find_dc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
|
||||
BOOL net_find_pdc(struct in_addr *server_ip, fstring server_name, const char *domain_name)
|
||||
{
|
||||
if (get_pdc_ip(domain_name, server_ip)) {
|
||||
fstring dc_name;
|
||||
|
||||
if (is_zero_ip(*server_ip))
|
||||
return False;
|
||||
|
||||
if (!lookup_dc_name(global_myname(), domain_name, server_ip, dc_name))
|
||||
if (!name_status_find(domain_name, 0x1b, 0x20, *server_ip, server_name))
|
||||
return False;
|
||||
|
||||
fstrcpy(server_name, dc_name);
|
||||
return True;
|
||||
} else
|
||||
}
|
||||
else
|
||||
return False;
|
||||
}
|
||||
|
||||
|
@ -124,11 +124,11 @@ static int net_lookup_ldap(int argc, const char **argv)
|
||||
|
||||
static int net_lookup_dc(int argc, const char **argv)
|
||||
{
|
||||
struct in_addr *ip_list, addr;
|
||||
struct ip_service *ip_list;
|
||||
struct in_addr addr;
|
||||
char *pdc_str = NULL;
|
||||
const char *domain=opt_target_workgroup;
|
||||
int count, i;
|
||||
BOOL list_ordered;
|
||||
|
||||
if (argc > 0)
|
||||
domain=argv[0];
|
||||
@ -140,12 +140,12 @@ 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, &list_ordered)) {
|
||||
if (!get_sorted_dc_list(domain, &ip_list, &count, False)) {
|
||||
SAFE_FREE(pdc_str);
|
||||
return 0;
|
||||
}
|
||||
for (i=0;i<count;i++) {
|
||||
char *dc_str = inet_ntoa(ip_list[i]);
|
||||
char *dc_str = inet_ntoa(ip_list[i].ip);
|
||||
if (!strequal(pdc_str, dc_str))
|
||||
d_printf("%s\n", dc_str);
|
||||
}
|
||||
|
@ -1781,7 +1781,7 @@ static int rpc_trustdom_establish(int argc, const char **argv)
|
||||
opt_user_name = acct_name;
|
||||
|
||||
/* find the domain controller */
|
||||
if (!net_find_dc(&server_ip, pdc_name, domain_name)) {
|
||||
if (!net_find_pdc(&server_ip, pdc_name, domain_name)) {
|
||||
DEBUG(0, ("Coulnd find domain controller for domain %s\n", domain_name));
|
||||
return -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user