summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/auth/auth_domain.c19
-rw-r--r--source3/libads/ldap.c19
-rw-r--r--source3/libsmb/namequery.c59
-rw-r--r--source3/nsswitch/winbindd_cm.c71
-rw-r--r--source3/rpcclient/samsync.c9
-rw-r--r--source3/smbd/change_trust_pw.c14
-rw-r--r--source3/utils/net.c25
-rw-r--r--source3/utils/net_lookup.c16
8 files changed, 109 insertions, 123 deletions
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 129c486562..e18d809efb 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -288,8 +288,23 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
if (time_now - last_change_time < 3600)
use_pdc_only = True;
- if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
- return NT_STATUS_NO_LOGON_SERVERS;
+ if (use_pdc_only) {
+ struct in_addr pdc_ip;
+
+ 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))
+ return NT_STATUS_NO_LOGON_SERVERS;
+ }
/*
* Firstly try and contact a PDC/BDC who has the same
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 2359dbd7ed..a59b78bf13 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -180,7 +180,7 @@ static BOOL ads_try_dns(ADS_STRUCT *ads)
/* try connecting to a ldap server via netbios */
static BOOL ads_try_netbios(ADS_STRUCT *ads)
{
- struct in_addr *ip_list;
+ struct in_addr *ip_list, pdc_ip;
int count;
int i;
char *workgroup = ads->server.workgroup;
@@ -192,20 +192,15 @@ static BOOL ads_try_netbios(ADS_STRUCT *ads)
DEBUG(6,("ads_try_netbios: looking for workgroup '%s'\n", workgroup));
/* try the PDC first */
- if (get_dc_list(True, workgroup, &ip_list, &count)) {
- 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);
+ 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(False, workgroup, &ip_list, &count)) {
+ if (get_dc_list(workgroup, &ip_list, &count)) {
for (i=0;i<count;i++) {
DEBUG(6,("ads_try_netbios: trying server '%s'\n",
inet_ntoa(ip_list[i])));
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 40a353fa8b..8fdf145625 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1206,54 +1206,87 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all...
#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */
}
-
/********************************************************
- Get the IP address list of the PDC/BDC's of a Domain.
+ Get the IP address list of the primary domain controller
+ for a domain.
*********************************************************/
-BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count)
+BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
{
- int name_type = pdc_only ? 0x1B : 0x1C;
+ struct in_addr *ip_list;
+ int count;
+
+ /* Look up #1B name */
+
+ if (!internal_resolve_name(domain, 0x1b, &ip_list, &count))
+ return False;
+
+ SMB_ASSERT(count == 1);
+
+ *ip = ip_list[0];
+ SAFE_FREE(ip_list);
+
+ 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)
+{
/*
* If it's our domain then
* use the 'password server' parameter.
*/
- if (strequal(group, lp_workgroup())) {
+ if (strequal(domain, lp_workgroup())) {
char *p;
char *pserver = lp_passwordserver();
fstring name;
int num_adresses = 0;
struct in_addr *return_iplist = NULL;
- if (! *pserver)
- return internal_resolve_name(group, name_type, ip_list, count);
+ if (!*pserver)
+ return internal_resolve_name(
+ domain, 0x1C, ip_list, count);
p = pserver;
+
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
if (strequal(name, "*"))
- return internal_resolve_name(group, name_type, ip_list, count);
+ return internal_resolve_name(
+ domain, 0x1C, ip_list, count);
num_adresses++;
}
+
if (num_adresses == 0)
- return internal_resolve_name(group, name_type, ip_list, count);
+ return internal_resolve_name(
+ domain, 0x1C, ip_list, count);
+
+ return_iplist = (struct in_addr *)malloc(
+ num_adresses * sizeof(struct in_addr));
- return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr));
- if(return_iplist == NULL) {
+ if (return_iplist == NULL) {
DEBUG(3,("get_dc_list: malloc fail !\n"));
return False;
}
+
p = pserver;
*count = 0;
+
while (next_token(&p,name,LIST_SEP,sizeof(name))) {
struct in_addr name_ip;
if (resolve_name( name, &name_ip, 0x20) == False)
continue;
return_iplist[(*count)++] = name_ip;
}
+
*ip_list = return_iplist;
+
return (*count != 0);
- } else
- return internal_resolve_name(group, name_type, ip_list, count);
+ }
+
+ return internal_resolve_name(domain, 0x1C, ip_list, count);
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index bbf5b90495..b4d5a664b2 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -140,70 +140,32 @@ static BOOL cm_ads_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
*/
static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring srv_name)
{
- struct in_addr *ip_list = NULL, exclude_ip;
+ struct in_addr *ip_list = NULL;
int count, i;
- zero_ip(&exclude_ip);
-
- /* Lookup domain controller name. Try the real PDC first to avoid
- SAM sync delays */
-
- if (get_dc_list(True, domain, &ip_list, &count)) {
- if (name_status_find(domain, 0x1c, 0x20, ip_list[0], srv_name)) {
- *dc_ip = ip_list[0];
- SAFE_FREE(ip_list);
- return True;
+ if (!get_dc_list(domain, &ip_list, &count)) {
+ 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;
}
- /* Didn't get name, remember not to talk to this DC. */
- exclude_ip = ip_list[0];
- SAFE_FREE(ip_list);
- }
- if (!get_dc_list(False, domain, &ip_list, &count)) {
- DEBUG(3, ("Could not look up dc's for domain %s\n", domain));
- return False;
- }
+ ip_list = (struct in_addr *)malloc(sizeof(struct in_addr));
- /* Remove the entry we've already failed with (should be the PDC). */
- for (i = 0; i < count; i++) {
- if (ip_equal( exclude_ip, ip_list[i]))
- zero_ip(&ip_list[i]);
- }
-
- /* Pick a nice close server */
- /* Look for DC on local net */
- for (i = 0; i < count; i++) {
- if (is_zero_ip(ip_list[i]))
- continue;
+ if (!ip_list)
+ return False;
- if (!is_local_net(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;
- }
- zero_ip(&ip_list[i]);
+ ip_list[0] = pdc_ip;
+ count = 1;
}
- /*
- * Secondly try and contact a random PDC/BDC.
- */
-
- i = (sys_random() % count);
-
- if (!is_zero_ip(ip_list[i]) &&
- name_status_find(domain, 0x1c, 0x20,
- ip_list[i], srv_name)) {
- *dc_ip = ip_list[i];
- SAFE_FREE(ip_list);
- return True;
+ /* Pick a nice close server */
+ if (count > 1) {
+ qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
}
- zero_ip(&ip_list[i]); /* Tried and failed. */
- /* Finally return first DC that we can contact using a node
- status */
for (i = 0; i < count; i++) {
if (is_zero_ip(ip_list[i]))
continue;
@@ -215,6 +177,7 @@ static BOOL cm_rpc_find_dc(const char *domain, struct in_addr *dc_ip, fstring sr
}
}
+
SAFE_FREE(ip_list);
return False;
diff --git a/source3/rpcclient/samsync.c b/source3/rpcclient/samsync.c
index fb07123b77..cbc3601812 100644
--- a/source3/rpcclient/samsync.c
+++ b/source3/rpcclient/samsync.c
@@ -494,8 +494,7 @@ static struct cli_state *init_connection(struct cli_state **cli,
char *password)
{
extern pstring global_myname;
- struct in_addr *dest_ip;
- int count;
+ struct in_addr pdc_ip;
fstring dest_host;
/* Initialise myname */
@@ -511,13 +510,13 @@ static struct cli_state *init_connection(struct cli_state **cli,
/* Look up name of PDC controller */
- if (!get_dc_list(True, lp_workgroup(), &dest_ip, &count)) {
+ if (!get_pdc_ip(lp_workgroup(), &pdc_ip)) {
DEBUG(0, ("Cannot find domain controller for domain %s\n",
lp_workgroup()));
return NULL;
}
- if (!lookup_dc_name(global_myname, lp_workgroup(), dest_ip,
+ if (!lookup_dc_name(global_myname, lp_workgroup(), pdc_ip,
dest_host)) {
DEBUG(0, ("Could not lookup up PDC name for domain %s\n",
lp_workgroup()));
@@ -525,7 +524,7 @@ static struct cli_state *init_connection(struct cli_state **cli,
}
if (NT_STATUS_IS_OK(cli_full_connection(cli, global_myname, dest_host,
- dest_ip, 0,
+ pdc_ip, 0,
"IPC$", "IPC",
username, domain,
password, 0))) {
diff --git a/source3/smbd/change_trust_pw.c b/source3/smbd/change_trust_pw.c
index 5da735e875..7cb9084072 100644
--- a/source3/smbd/change_trust_pw.c
+++ b/source3/smbd/change_trust_pw.c
@@ -105,12 +105,11 @@ account password for domain %s.\n", domain));
* We have been asked to dynamcially determine the IP addresses of the PDC.
*/
- struct in_addr *ip_list = NULL;
- int count = 0;
- int i;
+ struct in_addr pdc_ip;
+ fstring dc_name;
/* Use the PDC *only* for this. */
- if(!get_dc_list(True, domain, &ip_list, &count))
+ if(!get_pdc_ip(domain, &pdc_ip))
continue;
/*
@@ -118,16 +117,11 @@ account password for domain %s.\n", domain));
* address used as a string.
*/
- for(i = 0; i < count; i++) {
- fstring dc_name;
- if(!lookup_dc_name(global_myname, domain, &ip_list[i], dc_name))
+ if(!lookup_dc_name(global_myname, domain, &pdc_ip, dc_name))
continue;
if(NT_STATUS_IS_OK(res = modify_trust_password( domain, dc_name,
old_trust_passwd_hash)))
break;
- }
-
- SAFE_FREE(ip_list);
} else {
res = modify_trust_password( domain, remote_machine,
diff --git a/source3/utils/net.c b/source3/utils/net.c
index d38ca58622..27713d863f 100644
--- a/source3/utils/net.c
+++ b/source3/utils/net.c
@@ -180,20 +180,15 @@ BOOL net_find_server(unsigned flags, struct in_addr *server_ip, char **server_na
return False;
}
} else if (flags & NET_FLAGS_PDC) {
- struct in_addr *ip_list;
- int addr_count;
- if (get_dc_list(True /* PDC only*/, opt_target_workgroup, &ip_list, &addr_count)) {
+ struct in_addr pdc_ip;
+
+ if (get_pdc_ip(opt_target_workgroup, &pdc_ip)) {
fstring dc_name;
- if (addr_count < 1) {
- return False;
- }
-
- *server_ip = *ip_list;
- if (is_zero_ip(*server_ip))
+ if (is_zero_ip(pdc_ip))
return False;
- if (!lookup_dc_name(global_myname, opt_target_workgroup, server_ip, dc_name))
+ if (!lookup_dc_name(global_myname, opt_target_workgroup, &pdc_ip, dc_name))
return False;
*server_name = strdup(dc_name);
@@ -236,17 +231,9 @@ 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)
{
- struct in_addr *ip_list;
- int addr_count;
-
- if (get_dc_list(True /* PDC only*/, domain_name, &ip_list, &addr_count)) {
+ if (get_pdc_ip(domain_name, server_ip)) {
fstring dc_name;
- if (addr_count < 1) {
- return False;
- }
- *server_ip = *ip_list;
-
if (is_zero_ip(*server_ip))
return False;
diff --git a/source3/utils/net_lookup.c b/source3/utils/net_lookup.c
index f76b186251..32921de620 100644
--- a/source3/utils/net_lookup.c
+++ b/source3/utils/net_lookup.c
@@ -79,8 +79,8 @@ static int net_lookup_ldap(int argc, const char **argv)
#ifdef HAVE_LDAP
char *srvlist;
const char *domain;
- int rc, count;
- struct in_addr *addr;
+ int rc;
+ struct in_addr addr;
struct hostent *hostent;
if (argc > 0)
@@ -96,10 +96,10 @@ static int net_lookup_ldap(int argc, const char **argv)
}
DEBUG(9, ("Looking up DC for domain %s\n", domain));
- if (!get_dc_list(True, domain, &addr, &count))
+ if (!get_pdc_ip(domain, &addr))
return -1;
- hostent = gethostbyaddr((char *) &addr->s_addr, sizeof(addr->s_addr),
+ hostent = gethostbyaddr((char *) &addr.s_addr, sizeof(addr.s_addr),
AF_INET);
if (!hostent)
return -1;
@@ -124,7 +124,7 @@ 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;
+ struct in_addr *ip_list, addr;
char *pdc_str = NULL;
const char *domain=opt_target_workgroup;
int count, i;
@@ -133,13 +133,13 @@ static int net_lookup_dc(int argc, const char **argv)
domain=argv[0];
/* first get PDC */
- if (!get_dc_list(True, domain, &ip_list, &count))
+ if (!get_pdc_ip(domain, &addr))
return -1;
- asprintf(&pdc_str, "%s", inet_ntoa(*ip_list));
+ asprintf(&pdc_str, "%s", inet_ntoa(addr));
d_printf("%s\n", pdc_str);
- if (!get_dc_list(False, domain, &ip_list, &count)) {
+ if (!get_dc_list(domain, &ip_list, &count)) {
SAFE_FREE(pdc_str);
return 0;
}