1
0
mirror of https://github.com/samba-team/samba.git synced 2025-07-30 19:42:05 +03:00

This is a large patch (sorry). Migrate from struct in_addr

to struct sockaddr_storage in most places that matter (ie.
not the nmbd and NetBIOS lookups). This passes make test
on an IPv4 box, but I'll have to do more work/testing on
IPv6 enabled boxes. This should now give us a framework
for testing and finishing the IPv6 migration. It's at
the state where someone with a working IPv6 setup should
(theorecically) be able to type :
smbclient //ipv6-address/share
and have it work.
Jeremy.
(This used to be commit 98e154c312)
This commit is contained in:
Jeremy Allison
2007-10-24 14:16:54 -07:00
parent e01cbcb28e
commit f88b7a076b
64 changed files with 2224 additions and 1478 deletions

View File

@ -1,21 +1,22 @@
/*
/*
Unix SMB/CIFS implementation.
NetBIOS name cache module on top of gencache mechanism.
Copyright (C) Tim Potter 2002
Copyright (C) Rafal Szczesniak 2002
Copyright (C) Jeremy Allison 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@ -24,11 +25,10 @@
#define NBTKEY_FMT "NBT/%s#%02X"
/**
* Initialise namecache system. Function calls gencache
* initialisation function to perform necessary actions
*
*
* @return true upon successful initialisation of the cache or
* false on failure
**/
@ -38,7 +38,7 @@ bool namecache_enable(void)
/*
* Check if name caching disabled by setting the name cache
* timeout to zero.
*/
*/
if (lp_name_cache_timeout() == 0) {
DEBUG(5, ("namecache_enable: disabling netbios name cache\n"));
@ -48,18 +48,19 @@ bool namecache_enable(void)
/* Init namecache by calling gencache initialisation */
if (!gencache_init()) {
DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n"));
DEBUG(2, ("namecache_enable: "
"Couldn't initialise namecache on top of gencache.\n"));
return False;
}
/* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */
/* I leave it for now, though I don't think we really
* need this (mimir, 27.09.2002) */
DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d "
"seconds\n", lp_name_cache_timeout()));
return True;
}
/**
* Shutdown namecache. Routine calls gencache close function
* to safely close gencache file.
@ -67,19 +68,20 @@ bool namecache_enable(void)
* @return true upon successful shutdown of the cache or
* false on failure
**/
bool namecache_shutdown(void)
{
if (!gencache_shutdown()) {
DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n"));
DEBUG(2, ("namecache_shutdown: "
"Couldn't close namecache on top of gencache.\n"));
return False;
}
DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n"));
DEBUG(5, ("namecache_shutdown: "
"netbios namecache closed successfully.\n"));
return True;
}
/**
* Generates a key for netbios name lookups on basis of
* netbios name and type.
@ -92,7 +94,8 @@ bool namecache_shutdown(void)
* type number
*/
static char* namecache_key(const char *name, int name_type)
static char* namecache_key(const char *name,
int name_type)
{
char *keystr;
asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type);
@ -100,7 +103,6 @@ static char* namecache_key(const char *name, int name_type)
return keystr;
}
/**
* Store a name(s) in the name cache
*
@ -111,8 +113,10 @@ static char* namecache_key(const char *name, int name_type)
* ip addresses being stored
**/
bool namecache_store(const char *name, int name_type,
int num_names, struct ip_service *ip_list)
bool namecache_store(const char *name,
int name_type,
int num_names,
struct ip_service *ip_list)
{
time_t expiry;
char *key, *value_string;
@ -123,23 +127,35 @@ bool namecache_store(const char *name, int name_type,
* we use gecache call to avoid annoying debug messages about
* initialised namecache again and again...
*/
if (!gencache_init()) return False;
if (!gencache_init()) {
return False;
}
if (name_type > 255) {
return False; /* Don't store non-real name types. */
}
if ( DEBUGLEVEL >= 5 ) {
TALLOC_CTX *ctx = talloc_stackframe();
char *addr = NULL;
DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ",
num_names, num_names == 1 ? "": "es", name, name_type));
for (i = 0; i < num_names; i++)
DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip),
ip_list[i].port, (i == (num_names - 1) ? "" : ",")));
for (i = 0; i < num_names; i++) {
addr = print_canonical_sockaddr(ctx,
&ip_list[i].ss);
if (!addr) {
continue;
}
DEBUGADD(5, ("%s%s", addr,
(i == (num_names - 1) ? "" : ",")));
}
DEBUGADD(5, ("\n"));
TALLOC_FREE(ctx);
}
key = namecache_key(name, name_type);
if (!key) {
return False;
@ -155,9 +171,9 @@ bool namecache_store(const char *name, int name_type,
if (!ipstr_list_make(&value_string, ip_list, num_names)) {
SAFE_FREE(key);
SAFE_FREE(value_string);
return False;
return false;
}
/* set the entry */
ret = gencache_set(key, value_string, expiry);
SAFE_FREE(key);
@ -165,7 +181,6 @@ bool namecache_store(const char *name, int name_type,
return ret;
}
/**
* Look up a name in the cache.
*
@ -179,17 +194,22 @@ bool namecache_store(const char *name, int name_type,
* 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(const char *name,
int name_type,
struct ip_service **ip_list,
int *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 (!gencache_init())
if (!ip_list || !num_names) {
return False;
}
if (!gencache_init()) {
return False;
}
if (name_type > 255) {
return False; /* Don't fetch non-real name types. */
@ -197,7 +217,7 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis
*num_names = 0;
/*
/*
* Use gencache interface - lookup the key
*/
key = namecache_key(name, name_type);
@ -212,16 +232,16 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis
} else {
DEBUG(5, ("name %s#%02X found.\n", name, name_type));
}
/*
* Split up the stored value into the list of IP adresses
*/
*num_names = ipstr_list_parse(value, ip_list);
SAFE_FREE(key);
SAFE_FREE(value);
return *num_names > 0; /* true only if some ip has been fetched */
return *num_names > 0; /* true only if some ip has been fetched */
}
/**
@ -256,27 +276,30 @@ bool namecache_delete(const char *name, int name_type)
*
**/
static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr)
static void flush_netbios_name(const char *key,
const char *value,
time_t timeout,
void *dptr)
{
gencache_del(key);
DEBUG(5, ("Deleting entry %s\n", key));
}
/**
* Flush all names from the name cache.
* It's done by gencache_iterate()
*
* @return True upon successful deletion or
* False in case of an error
* @return true upon successful deletion or
* false in case of an error
**/
void namecache_flush(void)
{
if (!gencache_init())
if (!gencache_init()) {
return;
}
/*
/*
* iterate through each NBT cache's entry and flush it
* by flush_netbios_name function
*/
@ -286,40 +309,49 @@ void namecache_flush(void)
/* Construct a name status record key. */
static char *namecache_status_record_key(const char *name, int name_type1,
int name_type2, struct in_addr keyip)
static char *namecache_status_record_key(const char *name,
int name_type1,
int name_type2,
const struct sockaddr_storage *keyip)
{
char addr[INET6_ADDRSTRLEN];
char *keystr;
print_sockaddr(addr, sizeof(addr), keyip);
asprintf(&keystr, "NBT/%s#%02X.%02X.%s",
strupper_static(name), name_type1, name_type2, inet_ntoa(keyip));
strupper_static(name), name_type1, name_type2, addr);
return keystr;
}
/* Store a name status record. */
bool namecache_status_store(const char *keyname, int keyname_type,
int name_type, struct in_addr keyip,
int name_type, const struct sockaddr_storage *keyip,
const char *srvname)
{
char *key;
time_t expiry;
bool ret;
if (!gencache_init())
if (!gencache_init()) {
return False;
}
key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
return False;
expiry = time(NULL) + lp_name_cache_timeout();
ret = gencache_set(key, srvname, expiry);
if (ret)
DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname ));
else
DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key ));
if (ret) {
DEBUG(5, ("namecache_status_store: entry %s -> %s\n",
key, srvname ));
} else {
DEBUG(5, ("namecache_status_store: entry %s store failed.\n",
key ));
}
SAFE_FREE(key);
return ret;
@ -327,8 +359,11 @@ bool namecache_status_store(const char *keyname, int keyname_type,
/* Fetch a name status record. */
bool namecache_status_fetch(const char *keyname, int keyname_type,
int name_type, struct in_addr keyip, char *srvname_out)
bool namecache_status_fetch(const char *keyname,
int keyname_type,
int name_type,
const struct sockaddr_storage *keyip,
char *srvname_out)
{
char *key = NULL;
char *value = NULL;
@ -337,16 +372,19 @@ bool namecache_status_fetch(const char *keyname, int keyname_type,
if (!gencache_init())
return False;
key = namecache_status_record_key(keyname, keyname_type, name_type, keyip);
key = namecache_status_record_key(keyname, keyname_type,
name_type, keyip);
if (!key)
return False;
if (!gencache_get(key, &value, &timeout)) {
DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key));
DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n",
key));
SAFE_FREE(key);
return False;
} else {
DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value ));
DEBUG(5, ("namecache_status_fetch: key %s -> %s\n",
key, value ));
}
strlcpy(srvname_out, value, 16);