1
0
mirror of https://github.com/samba-team/samba.git synced 2025-06-19 23:17:05 +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 name_type,
int num_names, int num_names,
struct ip_service *ip_list); struct ip_service *ip_list);
bool namecache_fetch(const char *name, bool namecache_fetch(TALLOC_CTX *ctx,
const char *name,
int name_type, int name_type,
struct ip_service **ip_list, struct samba_sockaddr **sa_list,
int *num_names); size_t *num_names);
bool namecache_delete(const char *name, int name_type); bool namecache_delete(const char *name, int name_type);
void namecache_flush(void); void namecache_flush(void);
bool namecache_status_store(const char *keyname, int keyname_type, bool namecache_status_store(const char *keyname, int keyname_type,

View File

@ -23,6 +23,7 @@
#include "includes.h" #include "includes.h"
#include "lib/gencache.h" #include "lib/gencache.h"
#include "libsmb/namequery.h"
#define IPSTR_LIST_SEP "," #define IPSTR_LIST_SEP ","
#define IPSTR_LIST_CHAR ',' #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 ipstr ip string list to be parsed
* @param ip_list pointer to array of ip addresses which is * @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 * @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; char *token_str = NULL;
size_t i, count; size_t i, count;
size_t array_size;
if (!ipstr_list || !ip_list) *sa_list_out = NULL;
return 0;
count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1; array_size = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { sa_list = talloc_zero_array(frame,
DBG_ERR("malloc failed for %lu entries\n", struct samba_sockaddr,
(unsigned long)count); array_size);
if (sa_list == NULL) {
TALLOC_FREE(frame);
return 0; return 0;
} }
frame = talloc_stackframe(); count = 0;
for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str, for (i=0; next_token_talloc(frame, &ipstr_list, &token_str,
IPSTR_LIST_SEP) && i<count; i++ ) { IPSTR_LIST_SEP); i++ ) {
bool ok;
char *s = token_str; char *s = token_str;
char *p = strrchr(token_str, ':'); char *p = strrchr(token_str, ':');
struct sockaddr_storage ss;
/* Ensure we don't overrun. */
if (count >= array_size) {
break;
}
if (p) { if (p) {
*p = 0; *p = 0;
(*ip_list)[i].port = atoi(p+1); /* We now ignore the port. */
} }
/* convert single token to ip address */ /* 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'; *p = '\0';
} }
if (!interpret_string_addr(&(*ip_list)[i].ss, ok = interpret_string_addr(&ss, s, AI_NUMERICHOST);
s, if (!ok) {
AI_NUMERICHOST)) {
continue; 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); TALLOC_FREE(frame);
return count; return count;
@ -266,7 +287,7 @@ bool namecache_store(const char *name,
* *
* @param name netbios name to look up for * @param name netbios name to look up for
* @param name_type netbios name type of @param name * @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 * NULL otherwise
* @param num_names number of entries found * @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 * false if name isn't found in the cache or has expired
**/ **/
bool namecache_fetch(const char *name, bool namecache_fetch(TALLOC_CTX *ctx,
int name_type, const char *name,
struct ip_service **ip_list, int name_type,
int *num_names) struct samba_sockaddr **sa_list,
size_t *num_names)
{ {
char *key, *value; char *key, *value;
time_t timeout; 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) { if (name_type > 255) {
return false; /* Don't fetch non-real name types. */ 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 * 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(key);
TALLOC_FREE(value); TALLOC_FREE(value);

View File

@ -3186,9 +3186,11 @@ static NTSTATUS _internal_resolve_name(const char *name,
{ {
const char *tok; const char *tok;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
int i; size_t i;
size_t nc_count = 0;
bool ok; bool ok;
struct sockaddr_storage *ss_list = NULL; struct sockaddr_storage *ss_list = NULL;
struct samba_sockaddr *sa_list = NULL;
TALLOC_CTX *frame = talloc_stackframe(); TALLOC_CTX *frame = talloc_stackframe();
*return_iplist = NULL; *return_iplist = NULL;
@ -3232,17 +3234,50 @@ static NTSTATUS _internal_resolve_name(const char *name,
/* Check name cache */ /* 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) { if (ok) {
*return_count = remove_duplicate_addrs2(*return_iplist, /*
*return_count ); * Create a struct ip_service list from the
if (*return_count > 0) { * 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); TALLOC_FREE(frame);
return NT_STATUS_OK; return NT_STATUS_NO_MEMORY;
} else { }
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); TALLOC_FREE(frame);
return NT_STATUS_UNSUCCESSFUL; 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 */ /* set the name resolution order */