summaryrefslogtreecommitdiff
path: root/source3/libsmb/namequery.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-12-12 09:42:58 -0800
committerJeremy Allison <jra@samba.org>2007-12-12 09:42:58 -0800
commite3e16928c057b35b66bc814a507fc79b9e02084c (patch)
tree40ddc22a9e766042c634fbf7de87797e69ed2dfc /source3/libsmb/namequery.c
parentd818a93d073f5c15ffbb3b769348d25e49bc9848 (diff)
downloadsamba-e3e16928c057b35b66bc814a507fc79b9e02084c.tar.gz
samba-e3e16928c057b35b66bc814a507fc79b9e02084c.tar.bz2
samba-e3e16928c057b35b66bc814a507fc79b9e02084c.zip
Allow cliconnect to loop through multiple ip addresses
for a server. We should have been doing this for a while, but it's more critical with IPv6. Original patch fixed up by James. Jeremy. (This used to be commit 5c7f7629a97ef0929e00e52f1fae4386c984000b)
Diffstat (limited to 'source3/libsmb/namequery.c')
-rw-r--r--source3/libsmb/namequery.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 819147d48f..853fe979b7 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -1654,6 +1654,87 @@ bool resolve_name(const char *name,
}
/********************************************************
+ Internal interface to resolve a name into a list of IP addresses.
+ 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.
+*********************************************************/
+
+NTSTATUS resolve_name_list(TALLOC_CTX *ctx,
+ const char *name,
+ int name_type,
+ struct sockaddr_storage **return_ss_arr,
+ unsigned int *p_num_entries)
+{
+ struct ip_service *ss_list = NULL;
+ char *sitename = NULL;
+ int count = 0;
+ int i;
+ unsigned int num_entries;
+ NTSTATUS status;
+
+ *p_num_entries = 0;
+ *return_ss_arr = NULL;
+
+ if (is_ipaddress(name)) {
+ *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage);
+ if (!*return_ss_arr) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) {
+ TALLOC_FREE(*return_ss_arr);
+ return NT_STATUS_BAD_NETWORK_NAME;
+ }
+ *p_num_entries = 1;
+ return NT_STATUS_OK;
+ }
+
+ sitename = sitename_fetch(lp_realm()); /* wild guess */
+
+ status = internal_resolve_name(name, name_type, sitename,
+ &ss_list, &count,
+ lp_name_resolve_order());
+ SAFE_FREE(sitename);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* only return valid addresses for TCP connections */
+ for (i=0, num_entries = 0; i<count; i++) {
+ if (!is_zero_addr(&ss_list[i].ss) &&
+ !is_broadcast_addr(&ss_list[i].ss)) {
+ num_entries++;
+ }
+ }
+ if (num_entries == 0) {
+ SAFE_FREE(ss_list);
+ return NT_STATUS_BAD_NETWORK_NAME;
+ }
+
+ *return_ss_arr = TALLOC_ARRAY(ctx,
+ struct sockaddr_storage,
+ num_entries);
+ if (!(*return_ss_arr)) {
+ SAFE_FREE(ss_list);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0, num_entries = 0; i<count; i++) {
+ if (!is_zero_addr(&ss_list[i].ss) &&
+ !is_broadcast_addr(&ss_list[i].ss)) {
+ (*return_ss_arr)[num_entries++] = ss_list[i].ss;
+ }
+ }
+
+ status = NT_STATUS_OK;
+ *p_num_entries = num_entries;
+
+ SAFE_FREE(ss_list);
+ return NT_STATUS_OK;
+}
+
+/********************************************************
Find the IP address of the master browser or DMB for a workgroup.
*********************************************************/