From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: 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 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libsmb/namecache.c | 156 ++++++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 59 deletions(-) (limited to 'source3/libsmb/namecache.c') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index b569100d94..6a675d2ef2 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -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 . */ @@ -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 (!ip_list || !num_names) { + return False; + } - if (!gencache_init()) + 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); -- cgit