Make use of ZERO_STRUCT instead of memset in namequery.c
[jra/samba/.git] / source / libsmb / namequery.c
index 9650b5fc4555e4e0a20d6b663e7981c5e70138b9..893c9265fd241b07a21fadbb406fe968b08a9964 100644 (file)
@@ -791,12 +791,12 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
        *pp_name = NULL;
 
        while(!x_feof(fp) && !x_ferror(fp)) {
-               char *ip;
-               char *flags;
-               char *extra;
-               char *name;
+               char *ip = NULL;
+               char *flags = NULL;
+               char *extra = NULL;
+               char *name = NULL;
                const char *ptr;
-               char *ptr1;
+               char *ptr1 = NULL;
                int count = 0;
 
                *name_type = -1;
@@ -809,10 +809,6 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
                        continue;
                }
 
-               ip[0] = '\0';
-               name[0] = '\0';
-               flags[0] = '\0';
-
                ptr = line;
 
                if (next_token_talloc(ctx, &ptr, &ip, NULL))
@@ -839,6 +835,13 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type,
                        continue;
                }
 
+               if (!flags) {
+                       flags = talloc_strdup(ctx, "");
+                       if (!flags) {
+                               continue;
+                       }
+               }
+
                DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
                                        ip, name, flags));
 
@@ -1048,6 +1051,7 @@ NTSTATUS resolve_wins(const char *name,
                DEBUG(3,("resolve_wins: cannot receive WINS replies "
                        "on IPv6 address %s\n",
                        addr));
+               wins_srv_tags_free(wins_tags);
                return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -1157,7 +1161,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type,
                "Attempting lmhosts lookup for name %s<0x%x>\n",
                name, name_type));
 
-       fp = startlmhosts(dyn_LMHOSTSFILE);
+       fp = startlmhosts(get_dyn_LMHOSTSFILE());
 
        if ( fp == NULL )
                return NT_STATUS_NO_SUCH_FILE;
@@ -1244,6 +1248,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_flags = AI_ADDRCONFIG;
 
+#if !defined(HAVE_IPV6)
+       /* Unless we have IPv6, we really only want IPv4 addresses back. */
+       hints.ai_family = AF_INET;
+#endif
+
        ret = getaddrinfo(name,
                        NULL,
                        &hints,
@@ -1261,7 +1270,7 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
                        continue;
                }
 
-               memset(&ss, '\0', sizeof(ss));
+               ZERO_STRUCT(ss);
                memcpy(&ss, res->ai_addr, res->ai_addrlen);
 
                *return_count += 1;
@@ -1291,11 +1300,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
  Resolve via "ADS" method.
 *********************************************************/
 
-NTSTATUS resolve_ads(const char *name,
-                       int name_type,
-                       const char *sitename,
-                       struct ip_service **return_iplist,
-                       int *return_count)
+static NTSTATUS resolve_ads(const char *name,
+                           int name_type,
+                           const char *sitename,
+                           struct ip_service **return_iplist,
+                           int *return_count)
 {
        int                     i, j;
        NTSTATUS                status;
@@ -1414,14 +1423,13 @@ NTSTATUS resolve_ads(const char *name,
  resolve_hosts() when looking up DC's via SRV RR entries in DNS
 **********************************************************************/
 
-NTSTATUS internal_resolve_name(const char *name,
+static NTSTATUS internal_resolve_name(const char *name,
                                int name_type,
                                const char *sitename,
                                struct ip_service **return_iplist,
                                int *return_count,
                                const char *resolve_order)
 {
-       const char *name_resolve_list;
        char *tok;
        const char *ptr;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -1475,16 +1483,10 @@ NTSTATUS internal_resolve_name(const char *name,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!resolve_order) {
-               name_resolve_list = lp_name_resolve_order();
-       } else {
-               name_resolve_list = resolve_order;
-       }
-
-       if (!name_resolve_list[0]) {
+       if (!resolve_order[0]) {
                ptr = "host";
        } else {
-               ptr = name_resolve_list;
+               ptr = resolve_order;
        }
 
        /* iterate through the name resolution backends */
@@ -1645,6 +1647,87 @@ bool resolve_name(const char *name,
        return False;
 }
 
+/********************************************************
+ 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.
 *********************************************************/