]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: libsmb: Convert namecache_fetch() and it's only caller to return a talloc'ed...
authorJeremy Allison <jra@samba.org>
Wed, 26 Aug 2020 22:42:15 +0000 (15:42 -0700)
committerNoel Power <npower@samba.org>
Mon, 7 Sep 2020 13:23:42 +0000 (13:23 +0000)
Eventually everything will be talloced arrays of samba_sockaddr.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <npower@samba.org>
source3/include/proto.h
source3/libsmb/namecache.c
source3/libsmb/namequery.c

index 506e2e80fa117ec6b8395fecbe71610d1738d79f..ac7b36f005ba76c53a3c471e2396a2362c9ed6b2 100644 (file)
@@ -680,10 +680,11 @@ bool namecache_store(const char *name,
                        int name_type,
                        int num_names,
                        struct ip_service *ip_list);
-bool namecache_fetch(const char *name,
+bool namecache_fetch(TALLOC_CTX *ctx,
+                       const char *name,
                        int name_type,
-                       struct ip_service **ip_list,
-                       int *num_names);
+                       struct samba_sockaddr **sa_list,
+                       size_t *num_names);
 bool namecache_delete(const char *name, int name_type);
 void namecache_flush(void);
 bool namecache_status_store(const char *keyname, int keyname_type,
index fb4a4aac8c8a3f58949a7963c874597c486e5ad2..ae22c2fc26a4fc6aabb722602c3430bde9227503 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "includes.h"
 #include "lib/gencache.h"
+#include "libsmb/namequery.h"
 
 #define IPSTR_LIST_SEP ","
 #define IPSTR_LIST_CHAR        ','
@@ -114,35 +115,47 @@ static char *ipstr_list_make(TALLOC_CTX *ctx,
  *
  * @param ipstr ip string list to be parsed
  * @param ip_list pointer to array of ip addresses which is
- *        allocated by this function and must be freed by caller
+ *        talloced by this function and must be freed by caller
  * @return number of successfully parsed addresses
  **/
 
-static int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
+static int ipstr_list_parse(TALLOC_CTX *ctx,
+                       const char *ipstr_list,
+                       struct samba_sockaddr **sa_list_out)
 {
-       TALLOC_CTX *frame;
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct samba_sockaddr *sa_list = NULL;
        char *token_str = NULL;
        size_t i, count;
+       size_t array_size;
 
-       if (!ipstr_list || !ip_list)
-               return 0;
+       *sa_list_out = NULL;
 
-       count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
-       if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
-               DBG_ERR("malloc failed for %lu entries\n",
-                                       (unsigned long)count);
+       array_size = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
+       sa_list = talloc_zero_array(frame,
+                               struct samba_sockaddr,
+                               array_size);
+       if (sa_list == NULL) {
+               TALLOC_FREE(frame);
                return 0;
        }
 
-       frame = talloc_stackframe();
-       for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
-                               IPSTR_LIST_SEP) && i<count; i++ ) {
+       count = 0;
+       for (i=0; next_token_talloc(frame, &ipstr_list, &token_str,
+                               IPSTR_LIST_SEP); i++ ) {
+               bool ok;
                char *s = token_str;
                char *p = strrchr(token_str, ':');
+               struct sockaddr_storage ss;
+
+               /* Ensure we don't overrun. */
+               if (count >= array_size) {
+                       break;
+               }
 
                if (p) {
                        *p = 0;
-                       (*ip_list)[i].port = atoi(p+1);
+                       /* We now ignore the port. */
                }
 
                /* convert single token to ip address */
@@ -155,11 +168,19 @@ static int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
                        }
                        *p = '\0';
                }
-               if (!interpret_string_addr(&(*ip_list)[i].ss,
-                                       s,
-                                       AI_NUMERICHOST)) {
+               ok = interpret_string_addr(&ss, s, AI_NUMERICHOST);
+               if (!ok) {
+                       continue;
+               }
+               ok = sockaddr_storage_to_samba_sockaddr(&sa_list[count],
+                                                       &ss);
+               if (!ok) {
                        continue;
                }
+               count++;
+       }
+       if (count > 0) {
+               *sa_list_out = talloc_move(ctx, &sa_list);
        }
        TALLOC_FREE(frame);
        return count;
@@ -266,7 +287,7 @@ bool namecache_store(const char *name,
  *
  * @param name netbios name to look up for
  * @param name_type netbios name type of @param name
- * @param ip_list mallocated list of IP addresses if found in the cache,
+ * @param ip_list talloced list of IP addresses if found in the cache,
  *        NULL otherwise
  * @param num_names number of entries found
  *
@@ -274,19 +295,15 @@ bool namecache_store(const char *name,
  *         false if name isn't found in the cache or has expired
  **/
 
-bool namecache_fetch(const char *name,
-                       int name_type,
-                       struct ip_service **ip_list,
-                       int *num_names)
+bool namecache_fetch(TALLOC_CTX *ctx,
+               const char *name,
+               int name_type,
+               struct samba_sockaddr **sa_list,
+               size_t *num_names)
 {
        char *key, *value;
        time_t timeout;
 
-       /* exit now if null pointers were passed as they're required further */
-       if (!ip_list || !num_names) {
-               return false;
-       }
-
        if (name_type > 255) {
                return false; /* Don't fetch non-real name types. */
        }
@@ -312,7 +329,7 @@ bool namecache_fetch(const char *name,
        /*
         * Split up the stored value into the list of IP adresses
         */
-       *num_names = ipstr_list_parse(value, ip_list);
+       *num_names = ipstr_list_parse(ctx, value, sa_list);
 
        TALLOC_FREE(key);
        TALLOC_FREE(value);
index ba103f6c7fc28d224349a932c4520396f06c8e7f..2f7a4e81e6460ad6bdaea99e970883e0f2d972fe 100644 (file)
@@ -3186,9 +3186,11 @@ static NTSTATUS _internal_resolve_name(const char *name,
 {
        const char *tok;
        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-       int i;
+       size_t i;
+       size_t nc_count = 0;
        bool ok;
        struct sockaddr_storage *ss_list = NULL;
+       struct samba_sockaddr *sa_list = NULL;
        TALLOC_CTX *frame = talloc_stackframe();
 
        *return_iplist = NULL;
@@ -3232,17 +3234,50 @@ static NTSTATUS _internal_resolve_name(const char *name,
 
        /* Check name cache */
 
-       ok = namecache_fetch(name, name_type, return_iplist, return_count);
+       ok = namecache_fetch(frame,
+                               name,
+                               name_type,
+                               &sa_list,
+                               &nc_count);
        if (ok) {
-               *return_count = remove_duplicate_addrs2(*return_iplist,
-                                       *return_count );
-               if (*return_count > 0) {
+               /*
+                * Create a struct ip_service list from the
+                * returned samba_sockaddrs.
+                */
+               size_t count = 0;
+               struct ip_service *iplist = NULL;
+
+               iplist = SMB_MALLOC_ARRAY(struct ip_service, nc_count);
+               if (iplist == NULL) {
                        TALLOC_FREE(frame);
-                       return NT_STATUS_OK;
-               } else {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               count = 0;
+               for (i = 0; i < nc_count; i++) {
+                       if (is_zero_addr(&sa_list[i].u.ss)) {
+                               continue;
+                       }
+                       iplist[count].ss = sa_list[i].u.ss;
+                       iplist[count].port = 0;
+                       count++;
+               }
+               count = remove_duplicate_addrs2(iplist, count);
+               if (count == 0) {
+                       SAFE_FREE(iplist);
                        TALLOC_FREE(frame);
                        return NT_STATUS_UNSUCCESSFUL;
                }
+               /* Paranoia size_t -> int. */
+               if ((int)count < 0) {
+                       SAFE_FREE(iplist);
+                       TALLOC_FREE(frame);
+                       return NT_STATUS_INVALID_PARAMETER;
+               }
+
+               *return_count = (int)count;
+               *return_iplist = iplist;
+               TALLOC_FREE(frame);
+               return NT_STATUS_OK;
        }
 
        /* set the name resolution order */