1
0
mirror of https://github.com/samba-team/samba.git synced 2025-06-18 19:17:08 +03:00

s3: libsmb: Convert namecache_fetch() and it's only caller to return a talloc'ed array of struct samba_sockaddr.

Eventually everything will be talloced arrays of samba_sockaddr.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <npower@samba.org>
This commit is contained in:
Jeremy Allison 2020-08-26 15:42:15 -07:00 committed by Noel Power
parent 9ffb18856b
commit 4d4bf8eedb
3 changed files with 90 additions and 37 deletions

View 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,

View 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);

View 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 */