preview of winsdb stuff
Stefan (metze) Metzmacher
metze at metzemix.de
Mon Nov 18 11:24:06 GMT 2002
I fixed a seg fault
and some compiler warnings...
At 08:08 18.11.2002 +0100, Stefan (metze) Metzmacher wrote:
>Hi all,
>
>here's the preview of my winsdb stuff...
>
>it's working for me but must be tested a lot!
>
>Can some please test this?
>
>NOTE: this patch uses not the wins.tdb it uses wins_test.tdb, so if you
>want to test the conversion from the old wins.tdb format to the new you
>need to copy wins.tdb to wins_test.tdb first!
>
>The clean up of the winsserver code and the wrepld code follows in a
>seperate patch witch requires this one.
metze
-----------------------------------------------------------------------------
Stefan "metze" Metzmacher <metze at metzemix.de>
-------------- next part --------------
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/Makefile.in HEAD-nmbd/source/Makefile.in
--- HEAD/source/Makefile.in Fri Nov 15 18:42:55 2002
+++ HEAD-nmbd/source/Makefile.in Fri Nov 15 18:42:41 2002
@@ -297,7 +297,11 @@ MSDFS_OBJ = msdfs/msdfs.o
SMBD_OBJ = $(SMBD_OBJ_MAIN) $(SMBD_OBJ_BASE)
-NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
+WINSDB_OBJ = nmbd/winsdb_interface.o nmbd/winsdb_tdb.o
+
+NMBD_OBJ_MAIN = nmbd/nmbd.o
+
+NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd_globals.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
nmbd/nmbd_browsesync.o nmbd/nmbd_elections.o \
nmbd/nmbd_incomingdgrams.o nmbd/nmbd_incomingrequests.o \
@@ -310,14 +314,14 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
-NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
+NMBD_OBJ = $(NMBD_OBJ_MAIN) $(NMBD_OBJ1) $(WINSDB_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) \
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
WREPL_OBJ1 = wrepld/server.o wrepld/process.o wrepld/parser.o wrepld/socket.o \
wrepld/partners.o
-WREPL_OBJ = $(WREPL_OBJ1) $(PARAM_OBJ) $(UBIQX_OBJ) \
- $(PROFILE_OBJ) $(LIB_OBJ)
+WREPL_OBJ = $(WREPL_OBJ1) $(NMBD_OBJ1) $(WINSDB_OBJ) $(PARAM_OBJ) $(LIBSMB_OBJ) \
+ $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(SECRETS_OBJ) $(POPT_LIB_OBJ)
SWAT_OBJ1 = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
web/swat.o web/neg_lang.o
@@ -475,7 +479,8 @@ SMBFILTER_OBJ = utils/smbfilter.o $(LIBS
$(UBIQX_OBJ) $(LIB_OBJ)
PROTO_OBJ = $(SMBD_OBJ_MAIN) \
- $(SMBD_OBJ_SRV) $(NMBD_OBJ1) $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
+ $(SMBD_OBJ_SRV) $(NMBD_OBJ_MAIN) $(NMBD_OBJ1) $(WINSDB_OBJ) \
+ $(SWAT_OBJ1) $(LIB_OBJ) $(LIBSMB_OBJ) \
$(SMBW_OBJ1) $(SMBWRAPPER_OBJ1) $(SMBTORTURE_OBJ1) $(RPCCLIENT_OBJ1) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) \
$(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) \
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/include/includes.h HEAD-nmbd/source/include/includes.h
--- HEAD/source/include/includes.h Thu Oct 31 07:21:34 2002
+++ HEAD-nmbd/source/include/includes.h Thu Nov 14 14:04:04 2002
@@ -730,6 +730,7 @@ extern int errno;
#include "smb.h"
#include "smbw.h"
#include "nameserv.h"
+#include "winsdb.h"
#include "secrets.h"
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/include/nameserv.h HEAD-nmbd/source/include/nameserv.h
--- HEAD/source/include/nameserv.h Sat Aug 17 19:21:11 2002
+++ HEAD-nmbd/source/include/nameserv.h Thu Nov 14 15:36:35 2002
@@ -2,8 +2,9 @@
#define _NAMESERV_H_
/*
Unix SMB/CIFS implementation.
- NBT netbios header - version 2
- Copyright (C) Andrew Tridgell 1994-1998
+ NBT netbios header - version 3
+ Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Stefan (metze) Metzmacher 2002
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
@@ -21,12 +22,6 @@
*/
-#define INFO_VERSION "INFO/version"
-#define INFO_COUNT "INFO/num_entries"
-#define INFO_ID_HIGH "INFO/id_high"
-#define INFO_ID_LOW "INFO/id_low"
-#define ENTRY_PREFIX "ENTRY/"
-
#define PERMANENT_TTL 0
/* NTAS uses 2, NT uses 1, WfWg uses 0 */
@@ -176,57 +171,54 @@ enum name_source {LMHOSTS_NAME, REGISTER
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
enum packet_type {NMB_PACKET, DGRAM_PACKET};
-enum master_state
-{
- MST_NONE,
- MST_POTENTIAL,
- MST_BACKUP,
- MST_MSB,
- MST_BROWSER,
- MST_UNBECOMING_MASTER
-};
-
-enum domain_state
-{
- DOMAIN_NONE,
- DOMAIN_WAIT,
- DOMAIN_MST
-};
-
-enum logon_state
-{
- LOGON_NONE,
- LOGON_WAIT,
- LOGON_SRV
+enum master_state {
+ MST_NONE,
+ MST_POTENTIAL,
+ MST_BACKUP,
+ MST_MSB,
+ MST_BROWSER,
+ MST_UNBECOMING_MASTER
+};
+
+enum domain_state {
+ DOMAIN_NONE,
+ DOMAIN_WAIT,
+ DOMAIN_MST
+};
+
+enum logon_state {
+ LOGON_NONE,
+ LOGON_WAIT,
+ LOGON_SRV
};
struct subnet_record;
-struct nmb_data
-{
- uint16 nb_flags; /* Netbios flags. */
- int num_ips; /* Number of ip entries. */
- struct in_addr *ip; /* The ip list for this name. */
-
- enum name_source source; /* Where the name came from. */
-
- time_t death_time; /* The time the record must be removed (do not remove if 0). */
- time_t refresh_time; /* The time the record should be refreshed. */
-
- SMB_BIG_UINT id; /* unique id */
- struct in_addr wins_ip; /* the adress of the wins server this record comes from */
+struct nmb_addr {
+ struct in_addr ip; /* address of the record */
+ time_t ttl; /* The time the record should be refreshed. */
+ struct in_addr owner; /* the adress of the wins server this record comes from */
+};
- int wins_flags; /* similar to the netbios flags but different ! */
+struct nmb_data {
+ uint16 nb_flags; /* Netbios flags. */
+ int wins_flags; /* similar to the netbios flags but different ! */
+ struct in_addr owner; /* the adress of the wins server this record comes from */
+ SMB_BIG_UINT id; /* unique id */
+ time_t ttl; /* The time the record must be removed (do not remove if 0). */
+ time_t refresh_time; /* The time the record should be refreshed. */
+ int num_addrs; /* Number of ip_records entries. */
+ struct nmb_addr *addrs; /* The ip_record list for this name. */
};
/* This structure represents an entry in a local netbios name list. */
-struct name_record
- {
- ubi_trNode node[1];
- struct subnet_record *subnet;
- struct nmb_name name; /* The netbios name. */
- struct nmb_data data; /* The netbios data. */
- };
+struct name_record {
+ ubi_trNode node[1];
+ struct subnet_record *subnet;
+ enum name_source source; /* Where the name came from. */
+ struct nmb_name name; /* The netbios name. */
+ struct nmb_data data; /* address,... of the netbios name */
+};
/* Browser cache for synchronising browse lists. */
struct browse_cache_record
@@ -622,15 +614,17 @@ extern struct subnet_record *remote_broa
#define NEXT_SUBNET_INCLUDING_UNICAST(x) (get_next_subnet_maybe_unicast((x)))
/* wins replication record used between nmbd and wrepld */
+#define MAX_WINS_GROUP_IPS 25
typedef struct _WINS_RECORD {
char name[17];
char type;
int nb_flags;
int wins_flags;
+ struct in_addr owner;
SMB_BIG_UINT id;
+ time_t time;
int num_ips;
- struct in_addr ip[25];
- struct in_addr wins_ip;
+ struct in_addr ips[MAX_WINS_GROUP_IPS];
} WINS_RECORD;
/* To be removed. */
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/include/winsdb.h HEAD-nmbd/source/include/winsdb.h
--- HEAD/source/include/winsdb.h Thu Jan 1 01:00:00 1970
+++ HEAD-nmbd/source/include/winsdb.h Mon Nov 18 12:05:55 2002
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/CIFS implementation.
+ WINSDB structures
+
+ Copyright (C) Stefan (metze) Metzmacher 2002
+
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _WINSDB_H
+#define _WINSDB_H
+
+
+/* let it be 0 until we have a stable interface --metze */
+#define WINSDB_INTERFACE_VERSION 1
+
+/* Backend to use by default when no backend was specified */
+#define WINSDB_DEFAULT_BACKEND "tdb"
+
+typedef struct winsdb_context
+{
+ TALLOC_CTX *mem_ctx;
+ const char *backendname;
+ void *private_data;
+
+ NTSTATUS (*open) (struct winsdb_context *, BOOL write_db);
+ NTSTATUS (*close) (struct winsdb_context *);
+
+ NTSTATUS (*get_global_id) (struct winsdb_context *, SMB_BIG_UINT *current_id);
+ NTSTATUS (*store_global_id) (struct winsdb_context *, SMB_BIG_UINT current_id);
+
+ NTSTATUS (*get_next_record) (struct winsdb_context *, struct name_record **namerec);
+ NTSTATUS (*store_record) (struct winsdb_context *,const struct name_record *namerec);
+
+ void (*free_private_data)(struct winsdb_context **);
+} WINSDB_CONTEXT;
+
+typedef NTSTATUS (*winsdb_init_function)(WINSDB_CONTEXT *, const char *);
+
+struct winsdb_init_function_entry {
+ char *module_name;
+ /* Function to create a winsdb_context */
+ winsdb_init_function init;
+ struct winsdb_init_function_entry *prev;
+ struct winsdb_init_function_entry *next;
+};
+
+#endif /* _WINSDB_H */
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/asyncdns.c HEAD-nmbd/source/nmbd/asyncdns.c
--- HEAD/source/nmbd/asyncdns.c Mon Jul 29 06:34:56 2002
+++ HEAD-nmbd/source/nmbd/asyncdns.c Fri Nov 8 08:58:13 2002
@@ -24,13 +24,17 @@
Add a DNS result to the name cache.
****************************************************************************/
-static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
+static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr ip)
{
int name_type = question->name_type;
char *qname = question->name;
+ struct nmb_addr addr;
+ addr.ip = ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = 60*60;
- if (!addr.s_addr) {
+ if (!ip.s_addr) {
/* add the fail to WINS cache of names. give it 1 hour in the cache */
DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
(void)add_name_to_subnet( wins_server_subnet, qname, name_type,
@@ -39,8 +43,8 @@ static struct name_record *add_dns_resul
}
/* add it to our WINS cache of names. give it 2 hours in the cache */
- DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
-
+ DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(ip)));
+ addr.ttl = 2*60*60;
return( add_name_to_subnet( wins_server_subnet, qname, name_type,
NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd.c HEAD-nmbd/source/nmbd/nmbd.c
--- HEAD/source/nmbd/nmbd.c Wed Nov 13 19:52:36 2002
+++ HEAD-nmbd/source/nmbd/nmbd.c Thu Nov 14 18:39:06 2002
@@ -23,9 +23,9 @@
#include "includes.h"
-int ClientNMB = -1;
-int ClientDGRAM = -1;
-int global_nmb_port = -1;
+extern int ClientNMB;
+extern int ClientDGRAM;
+extern int global_nmb_port;
extern BOOL global_in_nmbd;
@@ -33,11 +33,11 @@ extern BOOL global_in_nmbd;
static BOOL is_daemon = False;
/* have we found LanMan clients yet? */
-BOOL found_lm_clients = False;
+extern BOOL found_lm_clients;
/* what server type are we currently */
-time_t StartupTime = 0;
+extern time_t StartupTime;
/**************************************************************************** **
Handle a SIGTERM in band.
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_become_lmb.c HEAD-nmbd/source/nmbd/nmbd_become_lmb.c
--- HEAD/source/nmbd/nmbd_become_lmb.c Wed Nov 13 19:52:36 2002
+++ HEAD-nmbd/source/nmbd/nmbd_become_lmb.c Wed Nov 13 20:22:59 2002
@@ -38,15 +38,25 @@ void insert_permanent_name_into_unicast(
if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
{
/* The name needs to be created on the unicast subnet. */
+ struct nmb_addr addr;
+ addr.ip = subrec->myip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
+
(void)add_name_to_subnet( unicast_subnet, nmbname->name,
nmbname->name_type, nb_type,
- PERMANENT_TTL, PERMANENT_NAME, 1, &subrec->myip);
+ PERMANENT_TTL, PERMANENT_NAME, 1, &addr);
}
else
{
/* The name already exists on the unicast subnet. Add our local
IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
+ struct nmb_addr addr;
+ addr.ip = subrec->myip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
+
+ add_ip_to_name_record( namerec, addr);
}
}
@@ -63,7 +73,7 @@ static void remove_permanent_name_from_u
{
/* Remove this broadcast subnet IP address from the name. */
remove_ip_from_name_record( namerec, subrec->myip);
- if(namerec->data.num_ips == 0)
+ if(namerec->data.num_addrs == 0)
remove_name_from_namelist( unicast_subnet, namerec);
}
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_elections.c HEAD-nmbd/source/nmbd/nmbd_elections.c
--- HEAD/source/nmbd/nmbd_elections.c Wed Nov 13 19:52:37 2002
+++ HEAD-nmbd/source/nmbd/nmbd_elections.c Thu Nov 14 18:31:10 2002
@@ -24,7 +24,7 @@
#include "includes.h"
/* Election parameters. */
-extern time_t StartupTime;
+time_t StartupTime;
/****************************************************************************
Send an election datagram packet.
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_globals.c HEAD-nmbd/source/nmbd/nmbd_globals.c
--- HEAD/source/nmbd/nmbd_globals.c Thu Jan 1 01:00:00 1970
+++ HEAD-nmbd/source/nmbd/nmbd_globals.c Fri Nov 15 08:08:38 2002
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/CIFS implementation.
+ NBT netbios routines and daemon - version 2
+ Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Jeremy Allison 1997-2002
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+int ClientNMB = -1;
+int ClientDGRAM = -1;
+int global_nmb_port = -1;
+
+/* have we found LanMan clients yet? */
+BOOL found_lm_clients = False;
+
+/* what server type are we currently */
+
+time_t StartupTime = 0;
+
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_incomingrequests.c HEAD-nmbd/source/nmbd/nmbd_incomingrequests.c
--- HEAD/source/nmbd/nmbd_incomingrequests.c Wed Nov 13 19:52:38 2002
+++ HEAD-nmbd/source/nmbd/nmbd_incomingrequests.c Wed Nov 13 20:23:00 2002
@@ -111,8 +111,8 @@ group release name %s from IP %s on subn
/* We only care about someone trying to release one of our names. */
if( namerec
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
+ && ( (namerec->source == SELF_NAME)
+ || (namerec->source == PERMANENT_NAME) ) )
{
rcode = ACT_ERR;
DEBUG(0, ("process_name_release_request: Attempt to release name %s from IP %s \
@@ -235,7 +235,7 @@ IP %s on subnet %s\n", nmb_namestr(quest
* later to queries.
*/
- if((namerec != NULL) && (namerec->data.source == WINS_PROXY_NAME))
+ if((namerec != NULL) && (namerec->source == WINS_PROXY_NAME))
{
remove_name_from_namelist( subrec, namerec );
namerec = NULL;
@@ -246,8 +246,8 @@ IP %s on subnet %s\n", nmb_namestr(quest
/* Unique name. */
if( (namerec != NULL)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME)
+ && ( (namerec->source == SELF_NAME)
+ || (namerec->source == PERMANENT_NAME)
|| NAME_GROUP(namerec) ) )
{
/* No-one can register one of Samba's names, nor can they
@@ -259,7 +259,7 @@ IP %s on subnet %s\n", nmb_namestr(quest
else if(namerec != NULL)
{
/* Update the namelist record with the new information. */
- namerec->data.ip[0] = from_ip;
+ namerec->data.addrs[0].ip = from_ip;
update_name_ttl(namerec, ttl);
DEBUG(3,("process_name_registration_request: Updated name record %s \
@@ -273,8 +273,8 @@ with IP %s on subnet %s\n",nmb_namestr(&
if( (namerec != NULL)
&& !NAME_GROUP(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) ) )
+ && ( (namerec->source == SELF_NAME)
+ || (namerec->source == PERMANENT_NAME) ) )
{
/* Disallow group names when we have a unique name. */
send_name_registration_response(ACT_ERR, 0, p);
@@ -350,8 +350,8 @@ subnet %s - name not found.\n", nmb_name
while (buf < bufend)
{
- if( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == PERMANENT_NAME) )
+ if( (namerec->source == SELF_NAME)
+ || (namerec->source == PERMANENT_NAME) )
{
int name_type = namerec->name.name_type;
@@ -473,8 +473,8 @@ void process_name_query_request(struct s
/* Check if it is a name that expired */
if (namerec &&
- ((namerec->data.death_time != PERMANENT_TTL) &&
- (namerec->data.death_time < p->timestamp))) {
+ ((namerec->data.ttl != PERMANENT_TTL) &&
+ (namerec->data.ttl < p->timestamp))) {
DEBUG(5,("process_name_query_request: expired name %s\n", nmb_namestr(&namerec->name)));
namerec = NULL;
}
@@ -490,9 +490,9 @@ void process_name_query_request(struct s
if (!bcast ||
(bcast && ((name_type == 0x1b) ||
- (namerec->data.source == SELF_NAME) ||
- (namerec->data.source == PERMANENT_NAME) ||
- ((namerec->data.source == WINS_PROXY_NAME) &&
+ (namerec->source == SELF_NAME) ||
+ (namerec->source == PERMANENT_NAME) ||
+ ((namerec->source == WINS_PROXY_NAME) &&
((name_type == 0) || (name_type == 0x20)))))) {
/* The requested name is a directed query, or it's SELF or PERMANENT or WINS_PROXY,
or it's a Domain Master type. */
@@ -505,9 +505,9 @@ void process_name_query_request(struct s
* replies to a broadcast query.
*/
- if (namerec->data.source == WINS_PROXY_NAME) {
- for( i = 0; i < namerec->data.num_ips; i++) {
- if (same_net(namerec->data.ip[i], subrec->myip, subrec->mask_ip)) {
+ if (namerec->source == WINS_PROXY_NAME) {
+ for( i = 0; i < namerec->data.num_addrs; i++) {
+ if (same_net(namerec->data.addrs[i].ip, subrec->myip, subrec->mask_ip)) {
DEBUG(5,("process_name_query_request: name %s is a WINS proxy name and is also on the same subnet (%s) as the requestor. Not replying.\n",
nmb_namestr(&namerec->name), subrec->subnet_name ));
return;
@@ -515,30 +515,30 @@ void process_name_query_request(struct s
}
}
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_ttl();
+ ttl = (namerec->data.ttl != PERMANENT_TTL) ?
+ namerec->data.ttl - p->timestamp : lp_max_ttl();
/* Copy all known ip addresses into the return data. */
/* Optimise for the common case of one IP address so
we don't need a malloc. */
- if (namerec->data.num_ips == 1) {
+ if (namerec->data.num_addrs == 1) {
prdata = rdata;
} else {
- if ((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL) {
+ if ((prdata = (char *)malloc( namerec->data.num_addrs * 6 )) == NULL) {
DEBUG(0,("process_name_query_request: malloc fail !\n"));
return;
}
}
- for (i = 0; i < namerec->data.num_ips; i++) {
+ for (i = 0; i < namerec->data.num_addrs; i++) {
set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+ putip((char *)&prdata[2+(i*6)], &namerec->data.addrs[i].ip);
}
sort_query_replies(prdata, i, p->ip);
- reply_data_len = namerec->data.num_ips * 6;
+ reply_data_len = namerec->data.num_addrs * 6;
success = True;
}
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_lmhosts.c HEAD-nmbd/source/nmbd/nmbd_lmhosts.c
--- HEAD/source/nmbd/nmbd_lmhosts.c Wed Jan 30 07:08:22 2002
+++ HEAD-nmbd/source/nmbd/nmbd_lmhosts.c Fri Nov 8 09:02:07 2002
@@ -60,14 +60,22 @@ void load_lmhosts_file(char *fname)
if(name_type == -1)
{
+ struct nmb_addr addr;
+ addr.ip = ipaddr;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
/* Add the (0) and (0x20) names directly into the namelist for this subnet. */
- (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
- (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ (void)add_name_to_subnet(subrec,name,0x00,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&addr);
+ (void)add_name_to_subnet(subrec,name,0x20,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&addr);
}
else
{
+ struct nmb_addr addr;
+ addr.ip = ipaddr;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
/* Add the given name type to the subnet namelist. */
- (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&ipaddr);
+ (void)add_name_to_subnet(subrec,name,name_type,(uint16)NB_ACTIVE,PERMANENT_TTL,source,1,&addr);
}
}
@@ -90,7 +98,7 @@ BOOL find_name_in_lmhosts(struct nmb_nam
FIND_ANY_NAME))==NULL)
return False;
- if(!NAME_IS_ACTIVE(namerec) || (namerec->data.source != LMHOSTS_NAME))
+ if(!NAME_IS_ACTIVE(namerec) || (namerec->source != LMHOSTS_NAME))
return False;
*namerecp = namerec;
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_mynames.c HEAD-nmbd/source/nmbd/nmbd_mynames.c
--- HEAD/source/nmbd/nmbd_mynames.c Wed Nov 13 19:52:38 2002
+++ HEAD-nmbd/source/nmbd/nmbd_mynames.c Wed Nov 13 20:23:00 2002
@@ -94,15 +94,25 @@ static void insert_refresh_name_into_uni
if((namerec = find_name_on_subnet(unicast_subnet, nmbname, FIND_SELF_NAME)) == NULL)
{
/* The name needs to be created on the unicast subnet. */
+ struct nmb_addr addr;
+ addr.ip = subrec->myip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
+
(void)add_name_to_subnet( unicast_subnet, nmbname->name,
nmbname->name_type, nb_type,
- MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &subrec->myip);
+ MIN(lp_max_ttl(), MAX_REFRESH_TIME), SELF_NAME, 1, &addr);
}
else
{
/* The name already exists on the unicast subnet. Add our local
IP for the given broadcast subnet to the name. */
- add_ip_to_name_record( namerec, subrec->myip);
+ struct nmb_addr addr;
+ addr.ip = subrec->myip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
+
+ add_ip_to_name_record( namerec, addr);
}
}
@@ -190,7 +200,7 @@ void release_wins_names(void)
namerec;
namerec = nextnamerec) {
nextnamerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.source == SELF_NAME)
+ if( (namerec->source == SELF_NAME)
&& !NAME_IS_DEREGISTERING(namerec) )
release_name( subrec, namerec, standard_success_release,
NULL, NULL);
@@ -210,9 +220,9 @@ void refresh_my_names(time_t t)
namerec;
namerec = (struct name_record *)ubi_trNext(namerec)) {
/* Each SELF name has an individual time to be refreshed. */
- if ((namerec->data.source == SELF_NAME) &&
+ if ((namerec->source == SELF_NAME) &&
(namerec->data.refresh_time < t) &&
- (namerec->data.death_time != PERMANENT_TTL)) {
+ (namerec->data.ttl != PERMANENT_TTL)) {
/* We cheat here and pretend the refresh is going to be
successful & update the refresh times. This stops
multiple refresh calls being done. We actually
@@ -221,7 +231,7 @@ void refresh_my_names(time_t t)
if (!is_refresh_already_queued(unicast_subnet, namerec)) {
wins_refresh_name(namerec);
}
- namerec->data.death_time = t + lp_max_ttl();
+ namerec->data.ttl = t + lp_max_ttl();
namerec->data.refresh_time = t + MIN(lp_max_ttl()/2, MAX_REFRESH_TIME);
}
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_namelistdb.c HEAD-nmbd/source/nmbd/nmbd_namelistdb.c
--- HEAD/source/nmbd/nmbd_namelistdb.c Wed Nov 13 19:52:38 2002
+++ HEAD-nmbd/source/nmbd/nmbd_namelistdb.c Fri Nov 15 12:23:11 2002
@@ -42,7 +42,7 @@ void set_samba_nb_type(void)
* Convert a NetBIOS name to upper case.
* ************************************************************************** **
*/
-static void upcase_name( struct nmb_name *target, struct nmb_name *source )
+void upcase_name( struct nmb_name *target, struct nmb_name *source )
{
int i;
@@ -73,11 +73,15 @@ static void update_name_in_namelist( str
(void)ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );
if( oldrec )
{
- SAFE_FREE( oldrec->data.ip );
+ SAFE_FREE( oldrec->data.addrs );
SAFE_FREE( oldrec );
}
} /* update_name_in_namelist */
+void add_record_to_subnet(struct subnet_record *subrec, struct name_record *namerec)
+{
+ update_name_in_namelist(subrec, namerec);
+}
/* ************************************************************************** **
* Remove a name from the namelist.
* ************************************************************************** **
@@ -87,7 +91,7 @@ void remove_name_from_namelist( struct s
{
(void)ubi_trRemove( subrec->namelist, namerec );
- SAFE_FREE(namerec->data.ip);
+ SAFE_FREE(namerec->data.addrs);
ZERO_STRUCTP(namerec);
SAFE_FREE(namerec);
@@ -112,8 +116,8 @@ struct name_record *find_name_on_subnet(
{
/* Self names only - these include permanent names. */
if( self_only
- && (name_ret->data.source != SELF_NAME)
- && (name_ret->data.source != PERMANENT_NAME) )
+ && (name_ret->source != SELF_NAME)
+ && (name_ret->source != PERMANENT_NAME) )
{
DEBUG( 9,
( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",
@@ -121,7 +125,7 @@ struct name_record *find_name_on_subnet(
return( NULL );
}
DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",
- subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );
+ subrec->subnet_name, nmb_namestr(nmbname), name_ret->source) );
return( name_ret );
}
DEBUG( 9,
@@ -159,10 +163,16 @@ struct name_record *find_name_for_remote
void update_name_ttl( struct name_record *namerec, int ttl )
{
time_t time_now = time(NULL);
+ int i;
- if( namerec->data.death_time != PERMANENT_TTL )
- namerec->data.death_time = time_now + ttl;
+ if( namerec->data.ttl != PERMANENT_TTL )
+ namerec->data.ttl = time_now + ttl;
+ for (i=0;i<namerec->data.num_addrs;i++) {
+ if (ip_equal(namerec->data.addrs[i].owner,wins_fake_ip())) {
+ namerec->data.addrs[i].ttl = time_now + ttl;
+ }
+ }
namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
namerec->subnet->namelist_changed = True;
@@ -178,12 +188,12 @@ struct name_record *add_name_to_subnet(
uint16 nb_flags,
int ttl,
enum name_source source,
- int num_ips,
- struct in_addr *iplist)
+ int num_addrs,
+ struct nmb_addr *addr_list)
{
struct name_record *namerec;
time_t time_now = time(NULL);
-
+
namerec = (struct name_record *)malloc( sizeof(*namerec) );
if( NULL == namerec )
{
@@ -192,9 +202,9 @@ struct name_record *add_name_to_subnet(
}
memset( (char *)namerec, '\0', sizeof(*namerec) );
- namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr)
- * num_ips );
- if( NULL == namerec->data.ip )
+ namerec->data.addrs = (struct nmb_addr *)malloc( sizeof(struct nmb_addr)
+ * num_addrs );
+ if( NULL == namerec->data.addrs )
{
DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );
@@ -216,20 +226,19 @@ struct name_record *add_name_to_subnet(
if( strequal( my_netbios_names(0), name ) )
namerec->data.nb_flags |= NB_PERM;
- /* Copy the IPs. */
- namerec->data.num_ips = num_ips;
- memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );
-
- /* Data source. */
- namerec->data.source = source;
-
/* Setup the death_time and refresh_time. */
if( ttl == PERMANENT_TTL )
- namerec->data.death_time = PERMANENT_TTL;
+ namerec->data.ttl = PERMANENT_TTL;
else
- namerec->data.death_time = time_now + ttl;
+ namerec->data.ttl = time_now + ttl;
namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);
+
+ /* Copy the IPs. */
+ namerec->data.num_addrs = num_addrs;
+ memcpy(namerec->data.addrs,addr_list,num_addrs * sizeof(struct nmb_addr));
+
+ namerec->source = source;
/* Now add the record to the name list. */
update_name_in_namelist( subrec, namerec );
@@ -237,7 +246,7 @@ struct name_record *add_name_to_subnet(
DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \
ttl=%d nb_flags=%2x to subnet %s\n",
nmb_namestr( &namerec->name ),
- inet_ntoa( *iplist ),
+ inet_ntoa( addr_list[0].ip ),
ttl,
(unsigned int)nb_flags,
subrec->subnet_name ) );
@@ -261,9 +270,14 @@ void standard_success_register(struct su
struct name_record *namerec;
namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME );
- if( NULL == namerec )
+ if( NULL == namerec ){
+ struct nmb_addr addr;
+ addr.ip = registered_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
(void)add_name_to_subnet( subrec, nmbname->name, nmbname->name_type,
- nb_flags, ttl, SELF_NAME, 1, ®istered_ip );
+ nb_flags, ttl, SELF_NAME, 1, &addr );
+ }
else
update_name_ttl( namerec, ttl );
}
@@ -298,12 +312,12 @@ on subnet %s\n",
static void remove_nth_ip_in_record( struct name_record *namerec, int ind)
{
- if( ind != namerec->data.num_ips )
- memmove( (char *)(&namerec->data.ip[ind]),
- (char *)(&namerec->data.ip[ind+1]),
- ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) );
+ if((ind > -1) && (ind < namerec->data.num_addrs))
+ memmove( (char *)(&namerec->data.addrs[ind]),
+ (char *)(&namerec->data.addrs[ind+1]),
+ ( namerec->data.num_addrs - ind - 1) * sizeof(struct nmb_addr) );
- namerec->data.num_ips--;
+ namerec->data.num_addrs--;
namerec->subnet->namelist_changed = True;
}
@@ -315,8 +329,8 @@ BOOL find_ip_in_name_record( struct name
{
int i;
- for(i = 0; i < namerec->data.num_ips; i++)
- if(ip_equal( namerec->data.ip[i], ip))
+ for(i = 0; i < namerec->data.num_addrs; i++)
+ if(ip_equal( namerec->data.addrs[i].ip, ip))
return True;
return False;
@@ -326,16 +340,16 @@ BOOL find_ip_in_name_record( struct name
Utility function to add an IP address to a name record.
******************************************************************/
-void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip )
+void add_ip_to_name_record( struct name_record *namerec, struct nmb_addr new_addr )
{
- struct in_addr *new_list;
+ struct nmb_addr *new_list;
/* Don't add one we already have. */
- if( find_ip_in_name_record( namerec, new_ip ) )
+ if( find_ip_in_name_record( namerec, new_addr.ip ) )
return;
- new_list = (struct in_addr *)malloc( (namerec->data.num_ips + 1)
- * sizeof(struct in_addr) );
+ new_list = (struct nmb_addr *)malloc( (namerec->data.num_addrs + 1)
+ * sizeof(struct nmb_addr) );
if( NULL == new_list )
{
DEBUG(0,("add_ip_to_name_record: Malloc fail !\n"));
@@ -343,13 +357,13 @@ void add_ip_to_name_record( struct name_
}
memcpy( (char *)new_list,
- (char *)namerec->data.ip,
- namerec->data.num_ips * sizeof(struct in_addr) );
- new_list[namerec->data.num_ips] = new_ip;
-
- SAFE_FREE(namerec->data.ip);
- namerec->data.ip = new_list;
- namerec->data.num_ips += 1;
+ (char *)namerec->data.addrs,
+ namerec->data.num_addrs * sizeof(struct nmb_addr) );
+ new_list[namerec->data.num_addrs] = new_addr;
+
+ SAFE_FREE(namerec->data.addrs);
+ namerec->data.addrs = new_list;
+ namerec->data.num_addrs++;
namerec->subnet->namelist_changed = True;
}
@@ -363,10 +377,10 @@ void remove_ip_from_name_record( struct
{
/* Try and find the requested ip address - remove it. */
int i;
- int orig_num = namerec->data.num_ips;
+ int orig_num = namerec->data.num_addrs;
for(i = 0; i < orig_num; i++)
- if( ip_equal( remove_ip, namerec->data.ip[i]) )
+ if( ip_equal( remove_ip, namerec->data.addrs[i].ip) )
{
remove_nth_ip_in_record( namerec, i);
break;
@@ -399,11 +413,11 @@ on subnet %s. Name was not found on subn
}
else
{
- int orig_num = namerec->data.num_ips;
+ int orig_num = namerec->data.num_addrs;
remove_ip_from_name_record( namerec, released_ip );
- if( namerec->data.num_ips == orig_num )
+ if( namerec->data.num_addrs == orig_num )
DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \
on subnet %s. This ip is not known for this name.\n",
nmb_namestr(nmbname),
@@ -411,7 +425,7 @@ on subnet %s. This ip is not known for t
subrec->subnet_name ) );
}
- if( namerec->data.num_ips == 0 )
+ if( namerec->data.num_addrs == 0 )
remove_name_from_namelist( subrec, namerec );
}
@@ -429,15 +443,15 @@ void expire_names_on_subnet(struct subne
namerec = next_namerec )
{
next_namerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) )
+ if( (namerec->data.ttl != PERMANENT_TTL)
+ && (namerec->data.ttl < t) )
{
- if( namerec->data.source == SELF_NAME )
+ if( namerec->source == SELF_NAME )
{
DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \
name %s\n",
subrec->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
+ namerec->data.ttl += 300;
namerec->subnet->namelist_changed = True;
continue;
}
@@ -475,9 +489,15 @@ void expire_names(time_t t)
void add_samba_names_to_subnet( struct subnet_record *subrec )
{
- struct in_addr *iplist = &subrec->myip;
- int num_ips = 1;
-
+ struct nmb_addr addr;
+ struct nmb_addr *addr_list = NULL;
+ int num_addrs = 1;
+
+ addr.ip = subrec->myip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = PERMANENT_TTL;
+
+ addr_list = &addr;
/* These names are added permanently (ttl of zero) and will NOT be
refreshed. */
@@ -489,9 +509,9 @@ void add_samba_names_to_subnet( struct s
int i;
/* Create an IP list containing all our known subnets. */
- num_ips = iface_count();
- iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) );
- if( NULL == iplist )
+ num_addrs = iface_count();
+ addr_list = (struct nmb_addr *)malloc( num_addrs * sizeof(struct nmb_addr) );
+ if( NULL == addr_list )
{
DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n"));
return;
@@ -499,22 +519,24 @@ void add_samba_names_to_subnet( struct s
for( bcast_subrecs = FIRST_SUBNET, i = 0;
bcast_subrecs;
- bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ )
- iplist[i] = bcast_subrecs->myip;
-
+ bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ ) {
+ addr_list[i].ip = bcast_subrecs->myip;
+ addr_list[i].owner = wins_fake_ip();
+ addr_list[i].ttl = PERMANENT_TTL;
+ }
}
(void)add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
+ PERMANENT_NAME, num_addrs, addr_list);
(void)add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
+ PERMANENT_NAME, num_addrs, addr_list);
(void)add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
+ PERMANENT_NAME, num_addrs, addr_list);
(void)add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL,
- PERMANENT_NAME, num_ips, iplist);
+ PERMANENT_NAME, num_addrs, addr_list);
- if(iplist != &subrec->myip)
- SAFE_FREE(iplist);
+ if(addr_list != &addr)
+ SAFE_FREE(addr_list);
}
/****************************************************************************
@@ -535,7 +557,7 @@ static void dump_subnet_namelist( struct
namerec = (struct name_record *)ubi_trNext( namerec ) )
{
x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name));
- switch(namerec->data.source)
+ switch(namerec->source)
{
case LMHOSTS_NAME:
src_type = "LMHOSTS_NAME";
@@ -564,13 +586,13 @@ static void dump_subnet_namelist( struct
}
x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags);
- if(namerec->data.death_time != PERMANENT_TTL)
+ if(namerec->data.ttl != PERMANENT_TTL)
{
- tm = LocalTime(&namerec->data.death_time);
- x_fprintf(fp, "death_time = %s\t", asctime(tm));
+ tm = LocalTime(&namerec->data.ttl);
+ x_fprintf(fp, "ttl = %s\t", asctime(tm));
}
else
- x_fprintf(fp, "death_time = PERMANENT\t");
+ x_fprintf(fp, "ttl = PERMANENT\t");
if(namerec->data.refresh_time != PERMANENT_TTL)
{
@@ -580,9 +602,9 @@ static void dump_subnet_namelist( struct
else
x_fprintf(fp, "refresh_time = PERMANENT\n");
- x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips);
- for(i = 0; i < namerec->data.num_ips; i++)
- x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i]));
+ x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_addrs);
+ for(i = 0; i < namerec->data.num_addrs; i++)
+ x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.addrs[i].ip));
x_fprintf(fp, "\n\n");
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_namequery.c HEAD-nmbd/source/nmbd/nmbd_namequery.c
--- HEAD/source/nmbd/nmbd_namequery.c Tue May 28 16:49:00 2002
+++ HEAD-nmbd/source/nmbd/nmbd_namequery.c Thu Nov 7 12:50:15 2002
@@ -179,8 +179,8 @@ static BOOL query_local_namelists(struct
return False;
if( NAME_IS_ACTIVE(namerec)
- && ( (namerec->data.source == SELF_NAME)
- || (namerec->data.source == LMHOSTS_NAME) ) )
+ && ( (namerec->source == SELF_NAME)
+ || (namerec->source == LMHOSTS_NAME) ) )
{
*namerecp = namerec;
return True;
@@ -220,27 +220,27 @@ BOOL query_name(struct subnet_record *su
rrec.rr_type = RR_TYPE_NB;
rrec.rr_class = RR_CLASS_IN;
rrec.ttl = PERMANENT_TTL;
- rrec.rdlength = namerec->data.num_ips * 6;
+ rrec.rdlength = namerec->data.num_addrs * 6;
if(rrec.rdlength > MAX_DGRAM_SIZE)
{
if( DEBUGLVL( 0 ) )
{
dbgtext( "query_name: nmbd internal error - " );
- dbgtext( "there are %d ip addresses ", namerec->data.num_ips );
+ dbgtext( "there are %d ip addresses ", namerec->data.num_addrs );
dbgtext( "for name %s.\n", nmb_namestr(&nmbname) );
}
return False;
}
- for( i = 0; i < namerec->data.num_ips; i++)
+ for( i = 0; i < namerec->data.num_addrs; i++)
{
set_nb_flags( &rrec.rdata[i*6], namerec->data.nb_flags );
- putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.ip[i]);
+ putip( &rrec.rdata[(i*6) + 2], (char *)&namerec->data.addrs[i].ip);
}
/* Call the success function directly. */
if(success_fn)
- (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.ip[0], &rrec);
+ (*(query_name_success_function)success_fn)(subrec, userdata, &nmbname, namerec->data.addrs[0].ip, &rrec);
return False;
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_nameregister.c HEAD-nmbd/source/nmbd/nmbd_nameregister.c
--- HEAD/source/nmbd/nmbd_nameregister.c Wed Nov 13 19:52:38 2002
+++ HEAD-nmbd/source/nmbd/nmbd_nameregister.c Wed Nov 13 20:23:00 2002
@@ -411,16 +411,16 @@ static void multihomed_register_name(str
only we will get away with this (only the WINS server
will ever query names from us on this subnet).
*/
- int num_ips=0;
+ int num_addrs=0;
int i, t;
struct subnet_record *subrec;
char **wins_tags;
- struct in_addr *ip_list;
+ struct nmb_addr *addr_list;
for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) )
- num_ips++;
+ num_addrs++;
- if((ip_list = (struct in_addr *)malloc(num_ips * sizeof(struct in_addr)))==NULL) {
+ if((addr_list = (struct nmb_addr *)malloc(num_addrs * sizeof(struct nmb_addr)))==NULL) {
DEBUG(0,("multihomed_register_name: malloc fail !\n"));
return;
}
@@ -428,12 +428,14 @@ static void multihomed_register_name(str
for (subrec = FIRST_SUBNET, i = 0;
subrec;
subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec), i++ ) {
- ip_list[i] = subrec->myip;
+ addr_list[i].ip = subrec->myip;
+ addr_list[i].owner = wins_fake_ip();
+ addr_list[i].ttl = lp_max_ttl();
}
-
- add_name_to_subnet(unicast_subnet, nmbname->name, nmbname->name_type,
+
+ add_name_to_subnet(unicast_subnet, nmbname->name, nmbname->name_type,
nb_flags, lp_max_ttl(), SELF_NAME,
- num_ips, ip_list);
+ num_addrs, addr_list);
/* get the list of wins tags - we try to register for each of them */
wins_tags = wins_srv_tags();
@@ -447,13 +449,13 @@ static void multihomed_register_name(str
for (t=0; wins_tags && wins_tags[t]; t++) {
multihomed_register_one(nmbname, nb_flags,
success_fn, fail_fn,
- ip_list[0],
+ addr_list[0].ip,
wins_tags[t]);
}
wins_srv_tags_free(wins_tags);
- SAFE_FREE(ip_list);
+ SAFE_FREE(addr_list);
}
@@ -515,7 +517,7 @@ void wins_refresh_name(struct name_recor
register_name_response,
register_name_timeout_response,
namerec->data.nb_flags,
- namerec->data.ip[0], wins_tags[t]);
+ namerec->data.addrs[0].ip, wins_tags[t]);
}
wins_srv_tags_free(wins_tags);
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_namerelease.c HEAD-nmbd/source/nmbd/nmbd_namerelease.c
--- HEAD/source/nmbd/nmbd_namerelease.c Thu Jun 27 16:37:17 2002
+++ HEAD-nmbd/source/nmbd/nmbd_namerelease.c Thu Nov 7 13:10:44 2002
@@ -148,22 +148,22 @@ static void wins_release_name(struct nam
wins_tags = wins_srv_tags();
for (t=0;wins_tags && wins_tags[t]; t++) {
- for (i = 0; i < namerec->data.num_ips; i++) {
- struct in_addr wins_ip = wins_srv_ip_tag(wins_tags[t], namerec->data.ip[i]);
+ for (i = 0; i < namerec->data.num_addrs; i++) {
+ struct in_addr wins_ip = wins_srv_ip_tag(wins_tags[t], namerec->data.addrs[i].ip);
- BOOL last_one = ((i==namerec->data.num_ips - 1) && !wins_tags[t+1]);
+ BOOL last_one = ((i==namerec->data.num_addrs - 1) && !wins_tags[t+1]);
if (queue_release_name(unicast_subnet,
release_name_response,
release_name_timeout_response,
- last_one?success_fn : NULL,
+ last_one? success_fn : NULL,
last_one? fail_fn : NULL,
last_one? userdata : NULL,
&namerec->name,
namerec->data.nb_flags,
- namerec->data.ip[i],
+ namerec->data.addrs[i].ip,
wins_ip) == NULL) {
DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
+ nmb_namestr(&namerec->name), inet_ntoa(namerec->data.addrs[i].ip) ));
}
}
}
@@ -184,9 +184,9 @@ void release_name(struct subnet_record *
int i;
/* Ensure it's a SELF name, and in the ACTIVE state. */
- if ((namerec->data.source != SELF_NAME) || !NAME_IS_ACTIVE(namerec)) {
+ if ((namerec->source != SELF_NAME) || !NAME_IS_ACTIVE(namerec)) {
DEBUG(0,("release_name: Cannot release name %s from subnet %s. Source was %d \n",
- nmb_namestr(&namerec->name), subrec->subnet_name, namerec->data.source));
+ nmb_namestr(&namerec->name), subrec->subnet_name, namerec->source));
return;
}
@@ -204,19 +204,19 @@ void release_name(struct subnet_record *
* Only call the success/fail function on the last one (it should
* only be done once).
*/
- for (i = 0; i < namerec->data.num_ips; i++) {
+ for (i = 0; i < namerec->data.num_addrs; i++) {
if (queue_release_name(subrec,
release_name_response,
release_name_timeout_response,
- (i == (namerec->data.num_ips - 1)) ? success_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? fail_fn : NULL,
- (i == (namerec->data.num_ips - 1)) ? userdata : NULL,
+ (i == (namerec->data.num_addrs - 1)) ? success_fn : NULL,
+ (i == (namerec->data.num_addrs - 1)) ? fail_fn : NULL,
+ (i == (namerec->data.num_addrs - 1)) ? userdata : NULL,
&namerec->name,
namerec->data.nb_flags,
- namerec->data.ip[i],
+ namerec->data.addrs[i].ip,
subrec->bcast_ip) == NULL) {
DEBUG(0,("release_name: Failed to send packet trying to release name %s IP %s\n",
- nmb_namestr(&namerec->name), inet_ntoa(namerec->data.ip[i]) ));
+ nmb_namestr(&namerec->name), inet_ntoa(namerec->data.addrs[i].ip) ));
}
}
}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_winsproxy.c HEAD-nmbd/source/nmbd/nmbd_winsproxy.c
--- HEAD/source/nmbd/nmbd_winsproxy.c Wed Jan 30 07:08:22 2002
+++ HEAD-nmbd/source/nmbd/nmbd_winsproxy.c Fri Nov 8 09:16:04 2002
@@ -34,10 +34,18 @@ static void wins_proxy_name_query_reques
struct subnet_record *orig_broadcast_subnet;
struct name_record *namerec;
uint16 nb_flags;
- int num_ips;
+ int num_addrs;
int i;
int ttl = 3600; /* By default one hour in the cache. */
- struct in_addr *iplist;
+ struct nmb_addr addr;
+ struct nmb_addr *addr_list;
+
+ if(rrec->ttl == PERMANENT_TTL)
+ ttl = lp_max_ttl();
+
+ addr.ip = ip;
+ addr.ttl = ttl;
+ addr.owner = wins_fake_ip();
/* Extract the original packet and the original broadcast subnet from
the userdata. */
@@ -48,39 +56,36 @@ static void wins_proxy_name_query_reques
nb_flags = get_nb_flags( rrec->rdata );
- num_ips = rrec->rdlength / 6;
- if(num_ips == 0)
+ num_addrs = rrec->rdlength / 6;
+ if(num_addrs == 0)
{
DEBUG(0,("wins_proxy_name_query_request_success: Invalid number of IP records (0) \
returned for name %s.\n", nmb_namestr(nmbname) ));
return;
}
- if(num_ips == 1)
- iplist = &ip;
+ if(num_addrs == 1)
+ addr_list = &addr;
else
{
- if((iplist = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr) )) == NULL)
+ if((addr_list = (struct nmb_addr *)malloc( num_addrs * sizeof(struct nmb_addr) )) == NULL)
{
DEBUG(0,("wins_proxy_name_query_request_success: malloc fail !\n"));
return;
}
- for(i = 0; i < num_ips; i++)
- putip( (char *)&iplist[i], (char *)&rrec->rdata[ (i*6) + 2]);
+ for(i = 0; i < num_addrs; i++)
+ putip( (char *)&addr_list[i].ip, (char *)&rrec->rdata[ (i*6) + 2]);
}
/* Add the queried name to the original subnet as a WINS_PROXY_NAME. */
- if(rrec == PERMANENT_TTL)
- ttl = lp_max_ttl();
-
namerec = add_name_to_subnet( orig_broadcast_subnet, nmbname->name,
nmbname->name_type, nb_flags, ttl,
- WINS_PROXY_NAME, num_ips, iplist );
+ WINS_PROXY_NAME, num_addrs, addr_list );
- if(iplist != &ip)
- SAFE_FREE(iplist);
+ if(addr_list != &addr)
+ SAFE_FREE(addr_list);
/*
* Check that none of the IP addresses we are returning is on the
@@ -92,9 +97,9 @@ returned for name %s.\n", nmb_namestr(nm
if(namerec && original_packet->packet.nmb.header.nm_flags.bcast)
{
- for( i = 0; i < namerec->data.num_ips; i++)
+ for( i = 0; i < namerec->data.num_addrs; i++)
{
- if( same_net( namerec->data.ip[i],
+ if( same_net( namerec->data.addrs[i].ip,
orig_broadcast_subnet->myip,
orig_broadcast_subnet->mask_ip ) )
{
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/nmbd_winsserver.c HEAD-nmbd/source/nmbd/nmbd_winsserver.c
--- HEAD/source/nmbd/nmbd_winsserver.c Mon Nov 18 06:44:22 2002
+++ HEAD-nmbd/source/nmbd/nmbd_winsserver.c Mon Nov 18 06:56:19 2002
@@ -2,7 +2,8 @@
Unix SMB/CIFS implementation.
NBT netbios routines and daemon - version 2
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Stefan (metze) Metzmacher 2002
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
@@ -22,9 +23,6 @@
#include "includes.h"
-#define WINS_LIST "wins.tdb"
-#define WINS_VERSION 1
-
/****************************************************************************
change the wins owner address in the record.
*****************************************************************************/
@@ -32,9 +30,57 @@ static void update_wins_owner(struct nam
{
if (namerec==NULL)
return;
- namerec->data.wins_ip=wins_ip;
+ namerec->data.owner=wins_ip;
+
+ /*fix me: maybe change the addresses owner too here! --metze*/
+}
+
+struct in_addr wins_fake_ip(void)
+{
+ static struct in_addr wins_ip;
+ static BOOL init = False;
+
+ if (!init) {
+ wins_ip = *interpret_addr2("0.0.0.0");
+ init = True;
+ }
+ return wins_ip;
}
+void dump_nmb_record(struct name_record *namerec)
+{
+ int i;
+
+ DEBUG(0,("Name: %-17s Owner: %15s ID: 0x%016X\n",
+ nmb_namestr(&namerec->name),inet_ntoa(namerec->data.owner),namerec->data.id));
+ DEBUGADD(0,("SOURCE: =0x%02X WINS_Flags: 0x%02X NB_FALGS: 0x%02X\n",
+ namerec->source,namerec->data.wins_flags,namerec->data.nb_flags));
+ {
+ char *ts, *nl;
+ struct tm *tm;
+ tm = LocalTime(&namerec->data.ttl);
+ ts = asctime(tm);
+ nl = strrchr_m( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(0,("TTL = %s\n", ts ));
+ }
+ for (i = 0; i < namerec->data.num_addrs; i++) {
+
+ DEBUGADD(0,("IP: %15s ",inet_ntoa(namerec->data.addrs[i].ip)));
+ DEBUGADD(0,("OWNER: %15s ",inet_ntoa(namerec->data.addrs[i].owner)));
+ {
+ char *ts, *nl;
+ struct tm *tm;
+ tm = LocalTime(&namerec->data.addrs[i].ttl);
+ ts = asctime(tm);
+ nl = strrchr_m( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+ DEBUGADD(0,("TTL = %s\n", ts ));
+ }
+ }
+}
/****************************************************************************
create the wins flags based on the nb flags and the input value.
*****************************************************************************/
@@ -50,13 +96,13 @@ static void update_wins_flag(struct name
if (namerec->name.name_type==0x1C)
namerec->data.wins_flags|=WINS_SGROUP;
else
- if (namerec->data.num_ips>1)
+ if (namerec->data.num_addrs>1)
namerec->data.wins_flags|=WINS_SGROUP;
else
namerec->data.wins_flags|=WINS_NGROUP;
} else {
/* can be unique or multi-homed */
- if (namerec->data.num_ips>1)
+ if (namerec->data.num_addrs>1)
namerec->data.wins_flags|=WINS_MHOMED;
else
namerec->data.wins_flags|=WINS_UNIQUE;
@@ -66,14 +112,14 @@ static void update_wins_flag(struct name
namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
/* the static bit is elsewhere */
- if (namerec->data.death_time == PERMANENT_TTL)
+ if (namerec->data.ttl == PERMANENT_TTL)
namerec->data.wins_flags|=WINS_STATIC;
/* and add the given bits */
namerec->data.wins_flags|=flags;
DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
- namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
+ namerec->data.nb_flags, (int)namerec->data.ttl, flags, namerec->data.wins_flags));
}
@@ -87,8 +133,14 @@ static void get_global_id_and_update(SMB
* with the value directly
*/
- static SMB_BIG_UINT general_id = 1;
+ static SMB_BIG_UINT general_id = 0;
+ static BOOL init = False;
+ if (!init) {
+ if (NT_STATUS_IS_ERR(winsdb_get_global_id(NULL,&general_id)))
+ general_id =1;
+ init = True;
+ }
DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
*current_id = general_id;
@@ -124,8 +176,8 @@ static void wins_hook(char *operation, s
namerec->name.name_type,
ttl);
- for (i=0;i<namerec->data.num_ips;i++) {
- p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
+ for (i=0;i<namerec->data.num_addrs;i++) {
+ p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.addrs[i].ip));
}
DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
@@ -222,10 +274,9 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
time_t time_now = time(NULL);
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
struct name_record *namerec = NULL;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ SMB_BIG_UINT tmp_id;
DEBUG(2,("initialise_wins: started\n"));
@@ -234,100 +285,36 @@ BOOL initialise_wins(void)
add_samba_names_to_subnet(wins_server_subnet);
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return True;
- }
-
- if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) {
- DEBUG(0,("Discarding invalid wins.dat file\n"));
- tdb_close(tdb);
- return True;
- }
+ winsdb_open(NULL,False);
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
-
- pstring name_type, name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int high, low;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len,i;
-
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr) continue;
-
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
-
- pstrcpy(name, name_type);
-
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags, &high, &low,
- ip_str, &ttl, &num_ips, &wins_flags);
-
- wins_ip=*interpret_addr2(ip_str);
-
- /* Don't reload replica records */
- if (!ip_equal(wins_ip, our_fake_ip))
- continue;
+ get_global_id_and_update(&tmp_id,False);
+
+ while (NT_STATUS_IS_OK(nt_status = winsdb_get_next_record(NULL,&namerec))) {
- /* Don't reload released or tombstoned records */
- if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE)
+ if (!namerec) {
continue;
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
- DEBUG(0,("initialise_wins: Malloc fail !\n"));
- return False;
}
-
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
-
+
/* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
-
- DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+ if ((namerec->data.ttl - 60) > time_now || namerec->data.ttl == PERMANENT_TTL) {
+ if(namerec->data.ttl != PERMANENT_TTL)
+ namerec->data.ttl -= time_now;
+ /* todo: also for each address owned by us --metze*/
- namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags,
- ttl, REGISTER_NAME, num_ips, ip_list);
- if (namerec!=NULL) {
- update_wins_owner(namerec, wins_ip);
- update_wins_flag(namerec, wins_flags);
- /* we don't reload the ID, on startup we restart at 1 */
- get_global_id_and_update(&namerec->data.id, True);
- }
+ add_record_to_subnet( wins_server_subnet, namerec);
+ dump_nmb_record(namerec);
} else {
DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+ namerec->name.name,
+ namerec->name.name_type,
+ namerec->data.ttl,
+ inet_ntoa(namerec->data.addrs[0].ip),
+ namerec->data.nb_flags));
}
-
- SAFE_FREE(ip_list);
}
-
- tdb_close(tdb);
+
+ winsdb_close(NULL);
DEBUG(2,("initialise_wins: done\n"));
return True;
}
@@ -399,7 +386,6 @@ void wins_process_name_refresh_request(s
struct name_record *namerec = NULL;
int ttl = get_ttl_from_packet(nmb);
struct in_addr from_ip;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
putip((char *)&from_ip,&nmb->additional->rdata[2]);
@@ -486,8 +472,9 @@ does not match group bit in WINS for thi
* if the record is a replica:
* we take ownership and update the version ID.
*/
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
- update_wins_owner(namerec, our_fake_ip);
+ /* this need fixing --metze*/
+ if (!ip_equal(namerec->data.owner, wins_fake_ip())) {
+ update_wins_owner(namerec, wins_fake_ip());
get_global_id_and_update(&namerec->data.id, True);
}
@@ -589,8 +576,9 @@ static void wins_register_query_fail(str
namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
if( (namerec != NULL)
- && (namerec->data.source == REGISTER_NAME)
- && ip_equal(rrec->packet->ip, *namerec->data.ip) )
+ && (namerec->source == REGISTER_NAME)
+ && ip_equal(rrec->packet->ip, namerec->data.addrs[0].ip) )
+ /* shouldn't we check all addrs here??? --metze*/
{
remove_name_from_namelist( subrec, namerec);
namerec = NULL;
@@ -674,7 +662,6 @@ void wins_process_name_registration_requ
struct name_record *namerec = NULL;
struct in_addr from_ip;
BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
putip((char *)&from_ip,&nmb->additional->rdata[2]);
@@ -720,8 +707,8 @@ not active - removing it.\n", nmb_namest
*/
if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
+ && ( (namerec->source == DNS_NAME)
+ || (namerec->source == DNSFAIL_NAME) ) )
{
DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
a dns lookup - removing it.\n", nmb_namestr(question) ));
@@ -734,11 +721,11 @@ a dns lookup - removing it.\n", nmb_name
* (ie. Don't allow any static names to be overwritten.
*/
- if((namerec != NULL) && (namerec->data.source != REGISTER_NAME))
+ if((namerec != NULL) && (namerec->source != REGISTER_NAME))
{
DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
+ nmb_namestr(question), namerec->source ));
send_wins_name_registration_response(RFS_ERR, 0, p);
return;
}
@@ -789,7 +776,12 @@ to register name %s from IP %s.\n", nmb_
* Check the ip address is not already in the group.
*/
if(!find_ip_in_name_record(namerec, from_ip)) {
- add_ip_to_name_record(namerec, from_ip);
+ struct nmb_addr addr;
+ addr.ip = from_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
+
+ add_ip_to_name_record(namerec, addr);
/* we need to update the record for replication */
get_global_id_and_update(&namerec->data.id, True);
@@ -801,7 +793,7 @@ to register name %s from IP %s.\n", nmb_
* it will update its own record.
*/
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
}
update_name_ttl(namerec, ttl);
@@ -867,9 +859,10 @@ is one of our (WINS server) names. Denyi
if( !registering_group_name
&& (namerec != NULL)
- && (namerec->data.num_ips == 1)
- && ip_equal( namerec->data.ip[0], from_ip )
- && ip_equal(namerec->data.wins_ip, our_fake_ip) )
+ && (namerec->data.num_addrs == 1)
+ && ip_equal( namerec->data.addrs[0].ip, from_ip )
+ && ip_equal(namerec->data.owner, wins_fake_ip()))
+ /* shouldn't we check each addr here??? --metze*/
{
update_name_ttl( namerec, ttl );
send_wins_name_registration_response( 0, ttl, p );
@@ -916,7 +909,8 @@ is one of our (WINS server) names. Denyi
* code. JRA.
*/
- query_name_from_wins_server( *namerec->data.ip,
+ query_name_from_wins_server( namerec->data.addrs[0].ip,
+ /* shouldn't we ... --metze */
question->name,
question->name_type,
wins_register_query_success,
@@ -928,12 +922,17 @@ is one of our (WINS server) names. Denyi
/*
* Name did not exist - add it.
*/
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
+ {
+ struct nmb_addr addr;
+ addr.ip = from_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
+ (void)add_name_to_subnet( subrec, question->name, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &addr);
+ }
if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
update_wins_flag(namerec, WINS_ACTIVE);
wins_hook("add", namerec, ttl);
}
@@ -960,7 +959,6 @@ static void wins_multihomed_register_que
struct name_record *namerec = NULL;
struct in_addr from_ip;
int ttl;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
@@ -980,7 +978,7 @@ static void wins_multihomed_register_que
namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
- if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) )
+ if( (namerec == NULL) || (namerec->source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) )
{
DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
a subsequent IP address.\n", nmb_namestr(question_name) ));
@@ -992,11 +990,16 @@ a subsequent IP address.\n", nmb_namestr
return;
}
- if(!find_ip_in_name_record(namerec, from_ip))
- add_ip_to_name_record(namerec, from_ip);
-
+ if(!find_ip_in_name_record(namerec, from_ip)) {
+ struct nmb_addr addr;
+ addr.ip = from_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
+
+ add_ip_to_name_record(namerec, addr);
+ }
get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
update_wins_flag(namerec, WINS_ACTIVE);
update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, orig_reg_packet);
@@ -1049,7 +1052,6 @@ void wins_process_multihomed_name_regist
struct name_record *namerec = NULL;
struct in_addr from_ip;
BOOL group = (nb_flags & NB_GROUP) ? True : False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
putip((char *)&from_ip,&nmb->additional->rdata[2]);
@@ -1117,8 +1119,8 @@ to register name %s from IP %s.", nmb_na
*/
if( (namerec != NULL)
- && ( (namerec->data.source == DNS_NAME)
- || (namerec->data.source == DNSFAIL_NAME) ) )
+ && ( (namerec->source == DNS_NAME)
+ || (namerec->source == DNSFAIL_NAME) ) )
{
DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
- removing it.\n", nmb_namestr(question) ));
@@ -1131,11 +1133,11 @@ to register name %s from IP %s.", nmb_na
* (ie. Don't allow any static names to be overwritten.
*/
- if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) )
+ if( (namerec != NULL) && (namerec->source != REGISTER_NAME) )
{
DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
to register name %s. Name already exists in WINS with source type %d.\n",
- nmb_namestr(question), namerec->data.source ));
+ nmb_namestr(question), namerec->source ));
send_wins_name_registration_response(RFS_ERR, 0, p);
return;
}
@@ -1179,11 +1181,16 @@ is one of our (WINS server) names. Denyi
* update the ttl. Update the version ID to force replication.
*/
if(!find_ip_in_name_record(namerec, from_ip)) {
+ struct nmb_addr addr;
+ addr.ip = from_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
+
+ add_ip_to_name_record(namerec, addr);
+
get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
update_wins_flag(namerec, WINS_ACTIVE);
-
- add_ip_to_name_record(namerec, from_ip);
wins_hook("add", namerec, ttl);
} else {
wins_hook("refresh", namerec, ttl);
@@ -1207,9 +1214,10 @@ is one of our (WINS server) names. Denyi
* If it's a replica, we need to become the wins owner
* to force the replication
*/
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (!ip_equal(namerec->data.owner, wins_fake_ip())) {
+ /* shouldn't we check each addr here??? --metze*/
get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
update_wins_flag(namerec, WINS_ACTIVE);
}
@@ -1260,7 +1268,8 @@ is one of our (WINS server) names. Denyi
* not the person who sent the packet
*/
- query_name_from_wins_server( namerec->data.ip[0],
+ query_name_from_wins_server( namerec->data.addrs[0].ip,
+ /* shouldn't we check each addr here??? --metze */
question->name,
question->name_type,
wins_multihomed_register_query_success,
@@ -1273,13 +1282,19 @@ is one of our (WINS server) names. Denyi
/*
* Name did not exist - add it.
*/
-
- (void)add_name_to_subnet( subrec, question->name, question->name_type,
- nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
+ {
+ struct nmb_addr addr;
+ addr.ip = from_ip;
+ addr.owner = wins_fake_ip();
+ addr.ttl = ttl;
+ DEBUG(0,("NAME: %-19s IP: %s\n",question->name,inet_ntoa(addr.ip)));
+ (void)add_name_to_subnet( subrec, question->name, question->name_type,
+ nb_flags, ttl, REGISTER_NAME, 1, &addr);
+ }
if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
get_global_id_and_update(&namerec->data.id, True);
- update_wins_owner(namerec, our_fake_ip);
+ update_wins_owner(namerec, wins_fake_ip());
update_wins_flag(namerec, WINS_ACTIVE);
wins_hook("add", namerec, ttl);
}
@@ -1296,7 +1311,7 @@ static void process_wins_dmb_query_reque
{
struct name_record *namerec = NULL;
char *prdata;
- int num_ips;
+ int num_addrs;
/*
* Go through all the ACTIVE names in the WINS db looking for those
@@ -1304,16 +1319,16 @@ static void process_wins_dmb_query_reque
* addresses we need to return.
*/
- num_ips = 0;
+ num_addrs = 0;
for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
namerec;
namerec = (struct name_record *)ubi_trNext( namerec ) )
{
if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b )
- num_ips += namerec->data.num_ips;
+ num_addrs += namerec->data.num_addrs;
}
- if(num_ips == 0)
+ if(num_addrs == 0)
{
/*
* There are no 0x1b names registered. Return name query fail.
@@ -1322,7 +1337,7 @@ static void process_wins_dmb_query_reque
return;
}
- if((prdata = (char *)malloc( num_ips * 6 )) == NULL)
+ if((prdata = (char *)malloc( num_addrs * 6 )) == NULL)
{
DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
return;
@@ -1334,7 +1349,7 @@ static void process_wins_dmb_query_reque
* return.
*/
- num_ips = 0;
+ num_addrs = 0;
for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
namerec;
namerec = (struct name_record *)ubi_trNext( namerec ) )
@@ -1342,11 +1357,11 @@ static void process_wins_dmb_query_reque
if(WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b)
{
int i;
- for(i = 0; i < namerec->data.num_ips; i++)
+ for(i = 0; i < namerec->data.num_addrs; i++)
{
- set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
- putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
- num_ips++;
+ set_nb_flags(&prdata[num_addrs * 6],namerec->data.nb_flags);
+ putip((char *)&prdata[(num_addrs * 6) + 2], &namerec->data.addrs[i].ip);
+ num_addrs++;
}
}
}
@@ -1361,7 +1376,7 @@ static void process_wins_dmb_query_reque
NMB_NAME_QUERY_OPCODE, /* opcode. */
lp_min_wins_ttl(), /* ttl. */
prdata, /* data to send. */
- num_ips*6); /* data length. */
+ num_addrs*6); /* data length. */
SAFE_FREE(prdata);
}
@@ -1383,33 +1398,34 @@ void send_wins_name_query_response(int r
if(rcode == 0)
{
- ttl = (namerec->data.death_time != PERMANENT_TTL) ?
- namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
+ ttl = (namerec->data.ttl != PERMANENT_TTL) ?
+ namerec->data.ttl - p->timestamp : lp_max_wins_ttl();
/* Copy all known ip addresses into the return data. */
/* Optimise for the common case of one IP address so
we don't need a malloc. */
- if( namerec->data.num_ips == 1 )
+ if( namerec->data.num_addrs == 1 )
prdata = rdata;
else
{
- if((prdata = (char *)malloc( namerec->data.num_ips * 6 )) == NULL)
+ if((prdata = (char *)malloc( namerec->data.num_addrs * 6 )) == NULL)
{
DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
return;
}
}
- for(i = 0; i < namerec->data.num_ips; i++)
+ for(i = 0; i < namerec->data.num_addrs; i++)
{
+ /* fix me: send only active addresse --metze */
set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
- putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
+ putip((char *)&prdata[2+(i*6)], &namerec->data.addrs[i].ip);
}
sort_query_replies(prdata, i, p->ip);
- reply_data_len = namerec->data.num_ips * 6;
+ reply_data_len = namerec->data.num_addrs * 6;
}
reply_netbios_packet(p, /* Packet to reply to. */
@@ -1470,7 +1486,7 @@ void wins_process_name_query_request(str
* If it's a DNSFAIL_NAME then reply name not found.
*/
- if( namerec->data.source == DNSFAIL_NAME )
+ if( namerec->source == DNSFAIL_NAME )
{
DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
nmb_namestr(question) ));
@@ -1482,8 +1498,8 @@ void wins_process_name_query_request(str
* If the name has expired then reply name not found.
*/
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < p->timestamp) )
+ if( (namerec->data.ttl != PERMANENT_TTL)
+ && (namerec->data.ttl < p->timestamp) )
{
DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
nmb_namestr(question) ));
@@ -1492,7 +1508,7 @@ void wins_process_name_query_request(str
}
DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
- nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
+ nmb_namestr(question), inet_ntoa(namerec->data.addrs[0].ip) ));
send_wins_name_query_response(0, p, namerec);
return;
@@ -1593,7 +1609,7 @@ to release name %s from IP %s.", nmb_nam
namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
if( (namerec == NULL)
- || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) )
+ || ((namerec != NULL) && (namerec->source != REGISTER_NAME)) )
{
send_wins_name_release_response(NAM_ERR, p);
return;
@@ -1636,33 +1652,34 @@ release name %s as this record is not an
send_wins_name_release_response(NAM_ERR, p);
return;
}
-
- /*
- * Check if the record is a 0x1c group
- * and has more then one ip
- * remove only this address.
+
+ /* check if the record is a 0x1c group
+ * and has more then one ip's
+ * remove only this address
+ *
+ * fix me: handle the owner of the ip --metze
*/
-
- if(releasing_group_name &&
- (question->name_type == 0x1c) &&
- (namerec->data.num_ips > 1)) {
- remove_ip_from_name_record(namerec, from_ip);
- DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
- inet_ntoa(from_ip),nmb_namestr(question)));
- send_wins_name_release_response(0, p);
- return;
+ if(releasing_group_name &&
+ (question->name_type == 0x1c) &&
+ (namerec->data.num_addrs > 1))
+ {
+ remove_ip_from_name_record(namerec, from_ip);
+ DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
+ inet_ntoa(from_ip),nmb_namestr(question)));
+ send_wins_name_release_response(0, p);
+ return;
}
-
+
/*
- * Send a release response.
- * Flag the name as released and update the ttl
- */
+ * Send a release response.
+ * Flag the name as released and update the ttl
+ */
send_wins_name_release_response(0, p);
-
+
namerec->data.wins_flags |= WINS_RELEASED;
update_name_ttl(namerec, EXTINCTION_INTERVAL);
-
+
wins_hook("delete", namerec, 0);
}
@@ -1675,7 +1692,6 @@ void initiate_wins_processing(time_t t)
static time_t lasttime = 0;
struct name_record *namerec;
struct name_record *next_namerec;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
if (!lasttime)
lasttime = t;
@@ -1692,30 +1708,31 @@ void initiate_wins_processing(time_t t)
namerec = next_namerec ) {
next_namerec = (struct name_record *)ubi_trNext( namerec );
- if( (namerec->data.death_time != PERMANENT_TTL)
- && (namerec->data.death_time < t) ) {
+ if( (namerec->data.ttl != PERMANENT_TTL)
+ && (namerec->data.ttl < t) ) {
- if( namerec->data.source == SELF_NAME ) {
+ if( namerec->source == SELF_NAME ) {
DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF name %s\n",
wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
- namerec->data.death_time += 300;
+ namerec->data.ttl += 300;
namerec->subnet->namelist_changed = True;
continue;
}
/* handle records, samba is the wins owner */
- if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (ip_equal(namerec->data.owner, wins_fake_ip())) {
+ /* shouldn't we check each addr here??? --metze */
switch (namerec->data.wins_flags | WINS_STATE_MASK) {
case WINS_ACTIVE:
namerec->data.wins_flags&=~WINS_STATE_MASK;
namerec->data.wins_flags|=WINS_RELEASED;
- namerec->data.death_time = t + EXTINCTION_INTERVAL;
+ namerec->data.ttl = t + EXTINCTION_INTERVAL;
DEBUG(3,("initiate_wins_processing: expiring %s\n", nmb_namestr(&namerec->name)));
break;
case WINS_RELEASED:
namerec->data.wins_flags&=~WINS_STATE_MASK;
namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
+ namerec->data.ttl = t + EXTINCTION_TIMEOUT;
get_global_id_and_update(&namerec->data.id, True);
DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
break;
@@ -1730,7 +1747,7 @@ void initiate_wins_processing(time_t t)
/* that's not as MS says it should be */
namerec->data.wins_flags&=~WINS_STATE_MASK;
namerec->data.wins_flags|=WINS_TOMBSTONED;
- namerec->data.death_time = t + EXTINCTION_TIMEOUT;
+ namerec->data.ttl = t + EXTINCTION_TIMEOUT;
DEBUG(3,("initiate_wins_processing: tombstoning %s\n", nmb_namestr(&namerec->name)));
case WINS_TOMBSTONED:
DEBUG(3,("initiate_wins_processing: deleting %s\n", nmb_namestr(&namerec->name)));
@@ -1758,12 +1775,6 @@ we are not the wins owner !\n", nmb_name
void wins_write_database(BOOL background)
{
struct name_record *namerec;
- pstring fname, fnamenew;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf;
- pstring key, buf;
- int len;
- int num_record=0;
SMB_BIG_UINT id;
if(!lp_we_are_a_wins_server())
@@ -1778,35 +1789,20 @@ void wins_write_database(BOOL background
}
}
- slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
- slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
-
- tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
- if (!tdb) {
- DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
- if (background)
- _exit(0);
- return;
- }
-
- DEBUG(3,("wins_write_database: Dump of WINS name list.\n"));
-
- tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION);
+ winsdb_open(NULL,True);
for (namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );
- namerec;
- namerec = (struct name_record *)ubi_trNext( namerec ) ) {
+ namerec;
+ namerec = (struct name_record *)ubi_trNext( namerec ) ) {
- int i;
struct tm *tm;
- DEBUGADD(3,("%-19s ", nmb_namestr(&namerec->name) ));
-
- if( namerec->data.death_time != PERMANENT_TTL ) {
+ DEBUG(3,("%-19s ", nmb_namestr(&namerec->name) ));
+
+ if( namerec->data.ttl != PERMANENT_TTL ) {
char *ts, *nl;
- tm = LocalTime(&namerec->data.death_time);
+ tm = LocalTime(&namerec->data.ttl);
ts = asctime(tm);
nl = strrchr_m( ts, '\n' );
if( NULL != nl )
@@ -1816,51 +1812,17 @@ void wins_write_database(BOOL background
} else
DEBUGADD(3,("TTL = PERMANENT "));
- for (i = 0; i < namerec->data.num_ips; i++)
- DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
-
- DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip)));
-
- if( namerec->data.source == REGISTER_NAME ) {
-
- /* store the type in the key to make the name unique */
- slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type);
-
- len = tdb_pack(buf, sizeof(buf), "dddfddd",
- (int)namerec->data.nb_flags,
- (int)(namerec->data.id>>32),
- (int)(namerec->data.id&0xffffffff),
- inet_ntoa(namerec->data.wins_ip),
- (int)namerec->data.death_time,
- namerec->data.num_ips,
- namerec->data.wins_flags);
-
- for (i = 0; i < namerec->data.num_ips; i++)
- len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i]));
-
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- dbuf.dsize = len;
- dbuf.dptr = buf;
- if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return;
-
- num_record++;
+ if( namerec->source == REGISTER_NAME ) {
+ if (NT_STATUS_IS_ERR(winsdb_store_record(NULL,namerec)))
+ return;
}
}
- /* store the number of records */
- tdb_store_int32(tdb, INFO_COUNT, num_record);
-
/* get and store the last used ID */
get_global_id_and_update(&id, False);
- tdb_store_int32(tdb, INFO_ID_HIGH, id>>32);
- tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff);
-
- tdb_close(tdb);
+ winsdb_store_global_id(NULL,id);
- chmod(fnamenew,0644);
- unlink(fname);
- rename(fnamenew,fname);
+ winsdb_close(NULL);
if (background)
_exit(0);
@@ -1876,7 +1838,6 @@ void nmbd_wins_new_entry(int msg_type, p
struct name_record *new_namerec = NULL;
struct nmb_name question;
BOOL overwrite=False;
- struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
int i;
if (buf==NULL)
@@ -1892,13 +1853,31 @@ void nmbd_wins_new_entry(int msg_type, p
/* record doesn't exist, add it */
if (namerec == NULL) {
+ struct nmb_addr *addr_list = NULL;
+
+
+ addr_list = (struct nmb_addr *)malloc(record->num_ips * sizeof(struct nmb_addr));
+
+ if (addr_list == NULL) {
+ DEBUG(0,("nmbd_wins_new_entry: malloc failed!\n"));
+ return;
+ }
+ for(i=0;i<record->num_ips;i++) {
+ addr_list[i].ip = record->ips[i];
+ addr_list[i].owner = record->owner;
+ addr_list[i].ttl = EXTINCTION_INTERVAL;
+ }
+
DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
+ record->name, record->type, inet_ntoa(record->owner)));
new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
+ EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, addr_list);
+
+ SAFE_FREE(addr_list);
+
if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
+ update_wins_owner(new_namerec, record->owner);
update_wins_flag(new_namerec, record->wins_flags);
new_namerec->data.id=record->id;
@@ -1912,16 +1891,16 @@ void nmbd_wins_new_entry(int msg_type, p
if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
/* the database record is a replica */
- if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
+ if (!ip_equal(namerec->data.owner, wins_fake_ip())) {
if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
- if (ip_equal(namerec->data.wins_ip, record->wins_ip))
+ if (ip_equal(namerec->data.owner, record->owner))
overwrite=True;
} else
overwrite=True;
} else {
/* we are the wins owner of the database record */
/* the 2 records have the same IP address */
- if (ip_equal(namerec->data.ip[0], record->ip[0])) {
+ if (ip_equal(namerec->data.addrs[0].ip, record->ips[0])) {
if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
get_global_id_and_update(&namerec->data.id, True);
else
@@ -1956,8 +1935,13 @@ void nmbd_wins_new_entry(int msg_type, p
if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
if (namerec->data.wins_flags&WINS_ACTIVE) {
for (i=0; i<record->num_ips; i++)
- if(!find_ip_in_name_record(namerec, record->ip[i]))
- add_ip_to_name_record(namerec, record->ip[i]);
+ if(!find_ip_in_name_record(namerec, record->ips[i])){
+ struct nmb_addr addr;
+ addr.ip = record->ips[i];
+ addr.owner = record->owner;
+ addr.ttl = EXTINCTION_INTERVAL;
+ add_ip_to_name_record(namerec, addr);
+ }
}
else
overwrite=True;
@@ -1973,10 +1957,10 @@ void nmbd_wins_new_entry(int msg_type, p
overwrite=True;
}
else {
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+ if (ip_equal(record->owner, namerec->data.owner))
overwrite=True;
- if (ip_equal(namerec->data.wins_ip, our_fake_ip))
+ if (ip_equal(namerec->data.owner, wins_fake_ip()))
if (namerec->data.wins_flags&WINS_UNIQUE)
get_global_id_and_update(&namerec->data.id, True);
@@ -1985,24 +1969,43 @@ void nmbd_wins_new_entry(int msg_type, p
if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
if (namerec->data.wins_flags&WINS_UNIQUE ||
namerec->data.wins_flags&WINS_MHOMED)
- if (ip_equal(record->wins_ip, namerec->data.wins_ip))
+ if (ip_equal(record->owner, namerec->data.owner))
overwrite=True;
}
if (overwrite == False)
DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
+ record->name, record->type, inet_ntoa(record->owner)));
else {
+ struct nmb_addr *addr_list = NULL;
+
DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n",
- record->name, record->type, inet_ntoa(record->wins_ip)));
+ record->name, record->type, inet_ntoa(record->owner)));
/* remove the old record and add a new one */
- remove_name_from_namelist( wins_server_subnet, namerec );
+ remove_name_from_namelist( wins_server_subnet, namerec );
+
+ addr_list = (struct nmb_addr *)malloc(record->num_ips * sizeof(struct nmb_addr));
+
+ if (addr_list == NULL) {
+ DEBUG(0,("nmbd_wins_new_entry: malloc failed!\n"));
+ return;
+ }
+ for(i=0;i<record->num_ips;i++) {
+ addr_list[i].ip = record->ips[i];
+ addr_list[i].owner = record->owner;
+ addr_list[i].ttl = EXTINCTION_INTERVAL;
+ }
+
new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags,
- EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
+ EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, addr_list);
+
+ SAFE_FREE(addr_list);
+
if (new_namerec!=NULL) {
- update_wins_owner(new_namerec, record->wins_ip);
+ dump_nmb_record(new_namerec);
+ update_wins_owner(new_namerec, record->owner);
update_wins_flag(new_namerec, record->wins_flags);
new_namerec->data.id=record->id;
@@ -2014,11 +2017,4 @@ void nmbd_wins_new_entry(int msg_type, p
}
}
-
-
-
-
-
-
-
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/winsdb_interface.c HEAD-nmbd/source/nmbd/winsdb_interface.c
--- HEAD/source/nmbd/winsdb_interface.c Thu Jan 1 01:00:00 1970
+++ HEAD-nmbd/source/nmbd/winsdb_interface.c Mon Nov 18 07:08:01 2002
@@ -0,0 +1,294 @@
+/*
+ Unix SMB/CIFS implementation.
+ WINSDB functions
+
+ Copyright (C) Stefan (metze) Metzmacher 2002
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+/** List of various built-in winsdb modules */
+
+const struct {
+ char *module_name;
+ /* Function to create a winsdb_context */
+ winsdb_init_function init;
+} builtin_winsdb_init_functions[] = {
+ { "tdb", winsdb_init_tdb },
+ { NULL, NULL}
+};
+
+static struct winsdb_init_function_entry *backends;
+
+static void lazy_initialize_winsdb()
+{
+ int i;
+ static BOOL initialised = False;
+
+ if(!initialised) {
+ initialised = True;
+
+ for(i = 0; builtin_winsdb_init_functions[i].module_name; i++) {
+ smb_register_winsdb(builtin_winsdb_init_functions[i].module_name, builtin_winsdb_init_functions[i].init, WINSDB_INTERFACE_VERSION);
+ }
+ }
+}
+
+BOOL smb_register_winsdb(char *name, winsdb_init_function init, int version)
+{
+ struct winsdb_init_function_entry *entry = backends;
+
+ if(version != WINSDB_INTERFACE_VERSION)
+ return False;
+
+ DEBUG(5,("Attempting to register winsdb backend %s\n", name));
+
+ /* Check for duplicates */
+ while(entry) {
+ if(strcasecmp(name, entry->module_name) == 0) {
+ DEBUG(0,("There already is a winsdb backend registered with the name %s!\n", name));
+ return False;
+ }
+ entry = entry->next;
+ }
+
+ entry = smb_xmalloc(sizeof(struct winsdb_init_function_entry));
+ entry->module_name = name;
+ entry->init = init;
+
+ DLIST_ADD(backends, entry);
+ DEBUG(5,("Successfully added winsdb backend '%s'\n", name));
+ return True;
+}
+
+/******************************************************************
+ Make a winsdb_context from scratch.
+ *******************************************************************/
+static NTSTATUS make_winsdb_context(WINSDB_CONTEXT **context)
+{
+ TALLOC_CTX *mem_ctx;
+
+ if (!context)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ mem_ctx = talloc_init_named("winsdb_context internal allocation context");
+
+ if (!mem_ctx) {
+ DEBUG(0, ("make_winsdb_context: talloc init failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *context = talloc(mem_ctx, sizeof(**context));
+ if (!*context) {
+ DEBUG(0, ("make_winsdb_context: talloc failed!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ZERO_STRUCTP(*context);
+
+ (*context)->mem_ctx = mem_ctx;
+
+ return NT_STATUS_OK;
+}
+
+/******************************************************************
+ Make a winsdb_context from scratch
+ *******************************************************************/
+NTSTATUS make_winsdb_context_by_name(WINSDB_CONTEXT **context, const char *backend_string)
+{
+ char *module_name = smb_xstrdup(backend_string);
+ char *module_location = NULL, *p;
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct winsdb_init_function_entry *entry;
+ int i;
+
+ lazy_initialize_winsdb();
+
+ entry = backends;
+
+ if (!NT_STATUS_IS_OK(nt_status = make_winsdb_context(context))) {
+ DEBUG(4,("make_winsdb_context failed\n"));
+ return nt_status;
+ }
+
+ p = strchr(module_name, ':');
+
+ if (p) {
+ *p = 0;
+ module_location = p+1;
+ trim_string(module_location, " ", " ");
+ }
+
+ trim_string(module_name, " ", " ");
+
+ DEBUG(5,("Attempting to find an winsdb backend to match %s (%s)\n", backend_string, module_name));
+ while(entry) {
+ if (strequal(entry->module_name, module_name)) {
+ DEBUG(5,("Found winsdb backend %s\n", module_name));
+ nt_status = entry->init(*context, module_location);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(5,("winsdb backend %s has a valid init\n", backend_string));
+ } else {
+ DEBUG(0,("winsdb backend %s did not correctly init (error was %s)\n", backend_string, nt_errstr(nt_status)));
+ }
+ SAFE_FREE(module_name);
+ return nt_status;
+ break; /* unreached */
+ }
+ entry = entry->next;
+ }
+
+ /* No such backend found */
+ SAFE_FREE(module_name);
+ return NT_STATUS_INVALID_PARAMETER;
+}
+
+/******************************************************************
+ Return an already initialised winsdb_context, to facilitate backward
+ compatibility (see functions below).
+*******************************************************************/
+
+static struct winsdb_context *winsdb_get_static_context(BOOL reload)
+{
+ static struct winsdb_context *winsdb_context = NULL;
+
+ if ((winsdb_context) && (reload)) {
+ winsdb_free_context(&winsdb_context);
+ if (NT_STATUS_IS_ERR(make_winsdb_context_by_name(&winsdb_context, lp_winsdb_backend()))) {
+ return NULL;
+ }
+ }
+
+ if (!winsdb_context) {
+ if (NT_STATUS_IS_ERR(make_winsdb_context_by_name(&winsdb_context, lp_winsdb_backend()))) {
+ return NULL;
+ }
+ }
+
+ return winsdb_context;
+}
+
+void winsdb_free_context(WINSDB_CONTEXT **context)
+{
+ if (context) {
+ if ((*context)->free_private_data) {
+ (*context)->free_private_data(context);
+ }
+ talloc_destroy((*context)->mem_ctx);
+ *context = NULL;
+ }
+}
+
+/****************************************************************************
+open the wins database for read or write
+*****************************************************************************/
+NTSTATUS winsdb_open(WINSDB_CONTEXT *context, BOOL write_db)
+{
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->open) {
+ DEBUG(0,("winsdb_open: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->open(context, write_db);
+}
+
+/****************************************************************************
+return the general ID value
+*****************************************************************************/
+NTSTATUS winsdb_get_global_id(WINSDB_CONTEXT *context, SMB_BIG_UINT *current_id)
+{
+ if (!current_id)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->get_global_id) {
+ DEBUG(0,("winsdb_get_global_id: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->get_global_id(context, current_id);
+}
+
+/****************************************************************************
+return the general ID value and increase it if requested
+*****************************************************************************/
+NTSTATUS winsdb_store_global_id(WINSDB_CONTEXT *context, SMB_BIG_UINT current_id)
+{
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->get_global_id) {
+ DEBUG(0,("winsdb_store_global_id: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->store_global_id(context, current_id);
+}
+
+/****************************************************************************
+get the next sored record from the wins database
+*****************************************************************************/
+NTSTATUS winsdb_get_next_record(WINSDB_CONTEXT *context, struct name_record **namerec)
+{
+ if (!namerec)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->get_next_record) {
+ DEBUG(0,("winsdb_get_next_record: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->get_next_record(context, namerec);
+}
+
+/****************************************************************************
+store a record in the wins database
+*****************************************************************************/
+NTSTATUS winsdb_store_record(WINSDB_CONTEXT *context, const struct name_record *namerec)
+{
+ if (!namerec)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->store_record) {
+ DEBUG(0,("winsdb_store_record: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->store_record(context, namerec);
+}
+
+/****************************************************************************
+close the wins database
+*****************************************************************************/
+NTSTATUS winsdb_close(WINSDB_CONTEXT *context)
+{
+ if (!context)
+ context = winsdb_get_static_context(False);
+
+ if (!context || !context->close) {
+ DEBUG(0,("winsdb_close: No context or no function found\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return context->close(context);
+}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/nmbd/winsdb_tdb.c HEAD-nmbd/source/nmbd/winsdb_tdb.c
--- HEAD/source/nmbd/winsdb_tdb.c Thu Jan 1 01:00:00 1970
+++ HEAD-nmbd/source/nmbd/winsdb_tdb.c Mon Nov 18 12:06:27 2002
@@ -0,0 +1,571 @@
+/*
+ Unix SMB/CIFS implementation.
+ WINSDB functions
+
+ Copyright (C) Stefan (metze) Metzmacher 2002
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+static int winsdb_tdb_debug_level = DBGC_ALL;
+
+#undef DBGC_CLASS
+#define DBGC_CLASS winsdb_tdb_debug_level
+
+#if 0 /* only for testing --metze */
+#define WINSDB_TDB_FILE "wins.tdb"
+#else
+#define WINSDB_TDB_FILE "wins_test.tdb"
+#endif
+
+#define WINSDB_TDB_VERSION_1 1
+#define WINSDB_TDB_VERSION_2 2
+#define WINSDB_TDB_VERSION WINSDB_TDB_VERSION_2
+
+#define WINSDB_TDB_INFO_VERSION "INFO/version"
+#define WINSDB_TDB_INFO_COUNT "INFO/num_entries"
+#define WINSDB_TDB_INFO_ID_HIGH "INFO/id_high"
+#define WINSDB_TDB_INFO_ID_LOW "INFO/id_low"
+#define WINSDB_TDB_ENTRY_PREFIX "ENTRY/"
+
+struct winsdb_tdb_privates {
+ char *path;
+ TDB_CONTEXT *tdb;
+ BOOL write_db;
+ int num_records;
+ BOOL not_first_key;
+ TDB_DATA current_kbuf;
+ struct name_record *next;
+ struct name_record **list;
+};
+
+static BOOL winsdb_tdb_convert_v1_to_v2(const char *path);
+
+/****************************************************************************
+close the wins database
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_close(WINSDB_CONTEXT *context)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+
+ DEBUG(5,("winsdb_tdb_close: started\n"));
+
+ if (privates->tdb){
+ if (privates->write_db) {
+ tdb_store_int32(privates->tdb, WINSDB_TDB_INFO_COUNT, privates->num_records);
+ }
+ tdb_close(privates->tdb);
+ privates->tdb = NULL;
+ privates->not_first_key = False;
+ }
+
+ DEBUG(5,("winsdb_tdb_close: done\n"));
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+open the wins database for read or write
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_open(WINSDB_CONTEXT *context, BOOL write_db)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+ int wins_version;
+
+ DEBUG(5,("winsdb_tdb_open: started\n"));
+
+ privates->write_db = write_db;
+ if (privates->tdb) {
+ DEBUG(4,("winsdb_tdb_open: a file is already open: close it before open in the desired modus\n"));
+ winsdb_tdb_close(context);
+ }
+
+ if (write_db) {
+ privates->tdb = tdb_open_log(privates->path, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (!privates->tdb) {
+ DEBUG(0,("initialise_wins: Can't open wins database file %s for write. Error was %s\n", privates->path, strerror(errno) ));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+ tdb_store_int32(privates->tdb, WINSDB_TDB_INFO_VERSION, WINSDB_TDB_VERSION);
+ return NT_STATUS_OK;
+ }
+
+
+ privates->tdb = tdb_open_log(privates->path, 0, TDB_DEFAULT, O_RDONLY, 0600);
+ if (!privates->tdb) {
+ DEBUG(0,("initialise_wins: Can't open wins database file %s for read. Error was %s\n", privates->path, strerror(errno) ));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if ((wins_version=tdb_fetch_int32(privates->tdb, WINSDB_TDB_INFO_VERSION)) != WINSDB_TDB_VERSION) {
+ winsdb_tdb_close(context);
+ switch(wins_version) {
+ case WINSDB_TDB_VERSION_1:
+ DEBUG(5,("Try to convert %s from WINDB_TDB_VERION_1 to WINDB_TDB_VERION_2!\n",
+ privates->path));
+ if (winsdb_tdb_convert_v1_to_v2(privates->path)) {
+ return winsdb_tdb_open(context,False);
+ } else {
+ DEBUG(0,("Can't convert %s from WINDB_TDB_VERION_1 to WINDB_TDB_VERION_2!\n",
+ privates->path));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+ break;
+ }
+ DEBUG(0,("Discarding invalid wins.tdb file: %s\n",privates->path));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ DEBUG(5,("winsdb_tdb_open: done\n"));
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+return the general ID value
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_get_global_id(WINSDB_CONTEXT *context, SMB_BIG_UINT *current_id)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+ int32 high=0,low=0;
+
+ DEBUG(5,("winsdb_tdb_get_global_id: started\n"));
+
+ if (!privates->tdb) {
+ DEBUG(0,("fail: tdb file is not open!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if (privates->write_db) {
+ DEBUG(0,("fail: tdb file is opened for write!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ high = tdb_fetch_int32(privates->tdb, WINSDB_TDB_INFO_ID_HIGH);
+ low = tdb_fetch_int32(privates->tdb, WINSDB_TDB_INFO_ID_LOW);
+
+
+ *current_id = high;
+ *current_id = *current_id>>32;
+ *current_id |= low & 0xffffffff;
+
+ DEBUG(5,("winsdb_tdb_get_global_id: done\n"));
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+return the general ID value
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_store_global_id(WINSDB_CONTEXT *context, SMB_BIG_UINT current_id)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+
+ DEBUG(5,("winsdb_tdb_store_global_id: started\n"));
+
+ if (!privates->tdb) {
+ DEBUG(0,("fail: tdb file is not open!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if (!privates->write_db) {
+ DEBUG(0,("fail: tdb file is opened for read!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ tdb_store_int32(privates->tdb, WINSDB_TDB_INFO_ID_HIGH,current_id>>32);
+ tdb_store_int32(privates->tdb, WINSDB_TDB_INFO_ID_LOW,current_id&0xffffffff);
+
+ DEBUG(5,("winsdb_tdb_store_global_id: done\n"));
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+get the next sored record from the wins database
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_get_next_record(WINSDB_CONTEXT *context, struct name_record **namerec)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+ TDB_DATA dbuf, new_kbuf;
+
+ DEBUG(5,("winsdb_tdb_get_next_record: started\n"));
+
+ if (!privates->tdb) {
+ DEBUG(0,("fail: tdb file is not open!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if (privates->write_db) {
+ DEBUG(0,("fail: tdb file is opened for write!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if (!privates->not_first_key) {
+ privates->current_kbuf = tdb_firstkey(privates->tdb);
+ privates->not_first_key = True;
+ } else {
+ new_kbuf = tdb_nextkey(privates->tdb, privates->current_kbuf);
+ SAFE_FREE(privates->current_kbuf.dptr);
+ privates->current_kbuf = new_kbuf;
+ }
+
+ if(privates->current_kbuf.dptr!=NULL) {
+ pstring name_type, name;
+ struct in_addr owner_ip, ip;
+ char *p;
+ int type = 0;
+ int temp_ttl;
+ int high, low;
+ struct nmb_addr *addr_list;
+ int len=0,i;
+
+ if (strncmp(privates->current_kbuf.dptr, WINSDB_TDB_ENTRY_PREFIX, strlen(WINSDB_TDB_ENTRY_PREFIX)) != 0) {
+ *namerec = NULL;
+ DEBUG(5,("winsdb_tdb_get_next_record: done (no entry prefix - skip)\n"));
+ return NT_STATUS_OK;
+ }
+
+ dbuf = tdb_fetch(privates->tdb, privates->current_kbuf);
+ if (!dbuf.dptr) {
+ *namerec = NULL;
+ DEBUG(0,("winsdb_tdb_get_next_record: done (no data)\n"));
+ return NT_STATUS_OK;
+ }
+
+ fstrcpy(name_type, privates->current_kbuf.dptr+strlen(WINSDB_TDB_ENTRY_PREFIX));
+
+ pstrcpy(name, name_type);
+
+ if((p = strchr(name,'#')) != NULL) {
+ *p = 0;
+ sscanf(p+1,"%x",&type);
+ }
+
+ *namerec = (struct name_record *)malloc(sizeof(struct name_record));
+ if (*namerec==NULL) {
+ DEBUG(0,("malloc for namerec failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ make_nmb_name(&(*namerec)->name, name, type);
+ upcase_name(&(*namerec)->name, NULL );
+
+ len = tdb_unpack(dbuf.dptr, dbuf.dsize, "ddddddd",
+ &(*namerec)->data.nb_flags,
+ &(*namerec)->data.wins_flags,
+ &(*namerec)->data.owner.s_addr,
+ &high, &low,
+ &(*namerec)->data.ttl,
+ &(*namerec)->data.num_addrs);
+
+ (*namerec)->data.id = high;
+ (*namerec)->data.id = (*namerec)->data.id<<32;
+ (*namerec)->data.id |= low;
+ (*namerec)->source = REGISTER_NAME;
+ (*namerec)->subnet = wins_server_subnet;
+
+ /* Allocate the space for the ip_list. */
+ if((addr_list = (struct nmb_addr *)malloc( (*namerec)->data.num_addrs * sizeof(struct nmb_addr))) == NULL) {
+ DEBUG(0,("malloc for addr_list failed\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < (*namerec)->data.num_addrs; i++) {
+ len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "ddd", &owner_ip.s_addr,&temp_ttl,&ip.s_addr);
+ addr_list[i].owner = owner_ip;
+ addr_list[i].ttl = temp_ttl;
+ addr_list[i].ip = ip;
+ }
+
+ (*namerec)->data.addrs = addr_list;
+ DEBUG(2,("winsdb_tdb_get_next_record: done\n"));
+ return NT_STATUS_OK;
+ }
+
+ DEBUG(2,("winsdb_tdb_get_next_record: done (last)\n"));
+ return NT_STATUS_NO_MORE_ENTRIES;
+}
+
+/****************************************************************************
+store a record in the wins database
+*****************************************************************************/
+static NTSTATUS winsdb_tdb_store_record(WINSDB_CONTEXT *context, const struct name_record *namerec)
+{
+ struct winsdb_tdb_privates *privates = (struct winsdb_tdb_privates *)context->private_data;
+ TDB_DATA kbuf, dbuf;
+ pstring key, buf;
+ int len=0;
+ int i;
+
+ DEBUG(5,("winsdb_tdb_store_record: started\n"));
+
+ if (!privates->tdb) {
+ DEBUG(0,("fail: tdb file is not open!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ if (!privates->write_db) {
+ DEBUG(0,("fail: tdb file is opened for read!\n"));
+ return NT_STATUS_UNSUCCESSFUL;/*maybe an other error here? --metze*/
+ }
+
+ DEBUG(3,("store name %-19s\n", nmb_namestr(&namerec->name) ));
+
+ /* store the type in the key to make the name unique */
+ slprintf(key, sizeof(key), "%s%s#%02x", WINSDB_TDB_ENTRY_PREFIX, namerec->name.name, namerec->name.name_type);
+ dump_nmb_record(namerec);
+ len = tdb_pack(buf, sizeof(buf), "ddddddd",
+ (int)namerec->data.nb_flags,
+ namerec->data.wins_flags,
+ (int)namerec->data.owner.s_addr,
+ (int)(namerec->data.id>>32),
+ (int)(namerec->data.id&0xffffffff),
+ (int)namerec->data.ttl,
+ namerec->data.num_addrs);
+ for (i = 0; i < namerec->data.num_addrs; i++) {
+ len += tdb_pack(buf+len, sizeof(buf)-len, "ddd",
+ (int)namerec->data.addrs[i].owner.s_addr,
+ (int)namerec->data.addrs[i].ttl,
+ (int)namerec->data.addrs[i].ip.s_addr);
+ }
+
+ kbuf.dsize = strlen(key)+1;
+ kbuf.dptr = key;
+ dbuf.dsize = len;
+ dbuf.dptr = buf;
+ if (tdb_store(privates->tdb, kbuf, dbuf, TDB_INSERT) != 0)
+ return NT_STATUS_UNSUCCESSFUL;
+
+ privates->num_records++;
+
+ DEBUG(5,("winsdb_tdb_store_record: done\n"));
+ return NT_STATUS_OK;
+}
+
+static void winsdb_tdb_free_private_data(WINSDB_CONTEXT **context)
+{
+ /* todo */
+}
+
+/*****************************************************
+Init the WINSDB TDB backend
+******************************************************/
+NTSTATUS winsdb_init_tdb(WINSDB_CONTEXT *context, const char *module_params)
+{
+ struct winsdb_tdb_privates *winsdb_tdb_state;
+
+ context->backendname = "winsdb_tdb";
+
+ context->open = winsdb_tdb_open;
+ context->close = winsdb_tdb_close;
+ context->get_global_id = winsdb_tdb_get_global_id;
+ context->store_global_id = winsdb_tdb_store_global_id;
+ context->get_next_record = winsdb_tdb_get_next_record;
+ context->store_record = winsdb_tdb_store_record;
+
+
+ context->free_private_data = winsdb_tdb_free_private_data;
+
+ winsdb_tdb_state = (struct winsdb_tdb_privates *)talloc_zero(context->mem_ctx, sizeof(struct winsdb_tdb_privates));
+ if (!winsdb_tdb_state) {
+ DEBUG(0, ("talloc() failed for winsdb tdb private_data!\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (module_params && *module_params) {
+ winsdb_tdb_state->path = talloc_strdup(context->mem_ctx, module_params);
+ if (!winsdb_tdb_state->path) {
+ DEBUG(0, ("talloc_strdup() failed.\n"));
+ return NT_STATUS_NO_MEMORY;
+ }
+ } else {
+ winsdb_tdb_state->path = talloc_strdup(context->mem_ctx, lock_path(WINSDB_TDB_FILE));
+ }
+
+ winsdb_tdb_state->not_first_key = False;
+ context->private_data = (void *)winsdb_tdb_state;
+
+ winsdb_tdb_debug_level = debug_add_class("winsdb_tdb");
+ if (winsdb_tdb_debug_level == -1) {
+ winsdb_tdb_debug_level = DBGC_ALL;
+ DEBUG(0, ("winsdb_tdb: Couldn't register custom debugging class!\n"));
+ } else DEBUG(2, ("winsdb_tdb: Debug class number of 'winsdb_tdb': %d\n", winsdb_tdb_debug_level));
+
+ DEBUG(5, ("Initializing winsdb_tdb\n"));
+ if (module_params)
+ DEBUG(10, ("Module Parameters: %s\n", module_params));
+
+ return NT_STATUS_OK;
+}
+
+
+/****************************************************************************
+Load the WINS database Version 1 .
+only for backward compatibility.
+*****************************************************************************/
+static BOOL winsdb_tdb_convert_v1_to_v2(const char *path)
+{
+ TDB_CONTEXT *old_tdb, *new_tdb;
+ TDB_DATA old_kbuf, new_kbuf, old_dbuf, new_dbuf, nextkey;
+ pstring fnamenew;
+ int num_records = 0;
+
+ if (!path) {
+ DEBUG(0,("winsdb_tdb_convert_v1_to_v2: no path given!\n"));
+ return False;
+ }
+ DEBUG(2,("winsdb_tdb_convert_v1_to_v2: for %s started\n",path));
+
+ if(!lp_we_are_a_wins_server())
+ return False;
+
+ old_tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDONLY, 0600);
+ if (!old_tdb) {
+ DEBUG(2,("winsdb_tdb_convert_v1_to_v2: Can't open wins database file %s. Error was %s\n", path, strerror(errno) ));
+ return False;
+ }
+
+ if (tdb_fetch_int32(old_tdb, WINSDB_TDB_INFO_VERSION) != WINSDB_TDB_VERSION_1) {
+ DEBUG(0,("Discarding invalid wins.tdb file not WINSDB_TDB_VERSION_1\n"));
+ tdb_close(old_tdb);
+ return False;
+ }
+
+ slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", path, (unsigned int)sys_getpid());
+
+ new_tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (!new_tdb) {
+ DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
+ return False;
+ }
+
+ tdb_store_int32(new_tdb, WINSDB_TDB_INFO_VERSION, WINSDB_TDB_VERSION);
+
+ for (old_kbuf = tdb_firstkey(old_tdb);
+ old_kbuf.dptr;
+ nextkey = tdb_nextkey(old_tdb, old_kbuf), safe_free(old_kbuf.dptr), old_kbuf=nextkey) {
+
+ pstring ip_str,owner_ip_str;
+ pstring new_buf;
+ pstring name;
+ int nb_flags;
+ int ttl;
+ unsigned int num_addrs;
+ int high, low;
+ struct in_addr owner_ip;
+ struct nmb_addr *addr_list;
+ int wins_flags;
+ int old_len,new_len,i;
+
+ if (strncmp(old_kbuf.dptr, WINSDB_TDB_ENTRY_PREFIX, strlen(WINSDB_TDB_ENTRY_PREFIX)) != 0)
+ continue;
+
+ fstrcpy(name, old_kbuf.dptr+strlen(WINSDB_TDB_ENTRY_PREFIX));
+
+ old_dbuf = tdb_fetch(old_tdb, old_kbuf);
+ if (!old_dbuf.dptr) continue;
+
+ old_len = tdb_unpack(old_dbuf.dptr, old_dbuf.dsize, "dddfddd",
+ &nb_flags, &high, &low,
+ owner_ip_str, &ttl, &num_addrs, &wins_flags);
+
+ owner_ip=*interpret_addr2(owner_ip_str);
+
+ /* Allocate the space for the ip_list. */
+ if((addr_list = (struct nmb_addr *)malloc( num_addrs * sizeof(struct nmb_addr))) == NULL) {
+ DEBUG(0,("initialise_wins: Malloc fail !\n"));
+ return False;
+ }
+
+ for (i = 0; i < num_addrs; i++) {
+ old_len += tdb_unpack(old_dbuf.dptr+old_len, old_dbuf.dsize-old_len, "f", ip_str);
+ addr_list[i].ip = *interpret_addr2(ip_str);
+ addr_list[i].ttl = ttl;
+ addr_list[i].owner = owner_ip;
+ }
+
+ new_len = tdb_pack(new_buf, sizeof(new_buf), "ddddddd",
+ (int)nb_flags,
+ (int)wins_flags,
+ (int)owner_ip.s_addr,
+ (int)high,
+ (int)low,
+ (int)ttl,
+ (int)num_addrs);
+
+ DEBUG(15,("Name: %-17s Owner: %15s\nWINS_Flags: 0x%02X NB_FALGS: 0x%02X ID: 0x%08X%08X\n",
+ name,inet_ntoa(owner_ip),wins_flags,nb_flags,high,low));
+ {
+ char *ts, *nl;
+ struct tm *tm;
+ tm = LocalTime((time_t)&ttl);
+ ts = asctime(tm);
+ nl = strrchr_m( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+
+ DEBUGADD(15,("TTL = %s\n", ts ));
+ }
+ for (i = 0; i < num_addrs; i++) {
+ new_len += tdb_pack(new_buf+new_len, sizeof(new_buf)-new_len, "ddd",
+ (int)addr_list[i].owner.s_addr,
+ (int)addr_list[i].ttl,
+ (int)addr_list[i].ip.s_addr);
+ DEBUGADD(15,("IP: %15s ",
+ inet_ntoa(addr_list[i].ip)));
+ DEBUGADD(15,("OWNER: %15s ",
+ inet_ntoa(addr_list[i].owner)));
+ {
+ char *ts, *nl;
+ struct tm *tm;
+ tm = LocalTime(&addr_list[i].ttl);
+ ts = asctime(tm);
+ nl = strrchr_m( ts, '\n' );
+ if( NULL != nl )
+ *nl = '\0';
+
+ DEBUGADD(15,("TTL = %s\n", ts ));
+ }
+ }
+
+ new_kbuf.dsize = old_dbuf.dsize;
+ new_kbuf.dptr = old_dbuf.dptr;
+ new_dbuf.dsize = new_len;
+ new_dbuf.dptr = new_buf;
+
+ SAFE_FREE(addr_list);
+
+ if (tdb_store(new_tdb, new_kbuf, new_dbuf, TDB_INSERT) != 0) {
+ return False;
+ }
+ num_records++;
+ }
+
+ /* store the number of records */
+ tdb_store_int32(new_tdb, WINSDB_TDB_INFO_COUNT, num_records);
+
+ tdb_store_int32(new_tdb, WINSDB_TDB_INFO_ID_HIGH, tdb_fetch_int32(old_tdb, WINSDB_TDB_INFO_ID_HIGH));
+ tdb_store_int32(new_tdb, WINSDB_TDB_INFO_ID_LOW, tdb_fetch_int32(old_tdb, WINSDB_TDB_INFO_ID_LOW));
+
+ tdb_close(old_tdb);
+ tdb_close(new_tdb);
+
+ chmod(fnamenew,0644);
+ unlink(path);
+ rename(fnamenew,path);
+
+ DEBUG(2,("winsdb_tdb_convert_v1_to_v2: done\n"));
+ return True;
+}
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/param/loadparm.c HEAD-nmbd/source/param/loadparm.c
--- HEAD/source/param/loadparm.c Wed Nov 13 19:52:39 2002
+++ HEAD-nmbd/source/param/loadparm.c Mon Nov 18 07:08:56 2002
@@ -220,6 +220,7 @@ typedef struct
BOOL bMsAddPrinterWizard;
BOOL bDNSproxy;
BOOL bWINSsupport;
+ char *szWinsdbBackend;
BOOL bWINSproxy;
BOOL bLocalMaster;
BOOL bPreferredMaster;
@@ -975,6 +976,7 @@ static struct parm_struct parm_table[] =
{"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
+ {"winsdb backend", P_STRING, P_GLOBAL, &Globals.szWinsdbBackend, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
{"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
{"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
@@ -1402,6 +1404,7 @@ static void init_globals(void)
Globals.bDomainLogons = False;
Globals.bBrowseList = True;
Globals.bWINSsupport = False;
+ string_set(&Globals.szWinsdbBackend, WINSDB_DEFAULT_BACKEND);
Globals.bWINSproxy = False;
Globals.bDNSproxy = True;
@@ -1613,6 +1616,7 @@ FN_GLOBAL_BOOL(lp_disable_netbios, &Glob
FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
+FN_GLOBAL_STRING(lp_winsdb_backend, &Globals.szWinsdbBackend)
FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/ubiqx/sys_include.h HEAD-nmbd/source/ubiqx/sys_include.h
--- HEAD/source/ubiqx/sys_include.h Wed Jan 26 22:25:35 2000
+++ HEAD-nmbd/source/ubiqx/sys_include.h Mon Nov 18 07:41:53 2002
@@ -40,6 +40,7 @@
*/
#define _PROTO_H_
#define _NAMESERV_H_
+#define _WINSDB_H
#define _HASH_H_
/* The main Samba system-adaptive header file.
diff -Npur --exclude=CVS --exclude=*.bak --exclude=*.o --exclude=*.po --exclude=.#* HEAD/source/wrepld/process.c HEAD-nmbd/source/wrepld/process.c
--- HEAD/source/wrepld/process.c Mon Jul 29 06:34:59 2002
+++ HEAD-nmbd/source/wrepld/process.c Fri Nov 15 08:32:31 2002
@@ -30,14 +30,6 @@ int partner_count;
TALLOC_CTX *mem_ctx;
-#define WINS_LIST "wins.tdb"
-#define INFO_VERSION "INFO/version"
-#define INFO_COUNT "INFO/num_entries"
-#define INFO_ID_HIGH "INFO/id_high"
-#define INFO_ID_LOW "INFO/id_low"
-#define ENTRY_PREFIX "ENTRY/"
-
-
/*******************************************************************
fill the header of a reply.
********************************************************************/
@@ -195,18 +187,13 @@ read the last ID from the wins tdb file.
****************************************************************************/
static void get_our_last_id(WINS_OWNER *wins_owner)
{
- TDB_CONTEXT *tdb;
-
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("get_our_last_id: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
+ SMB_BIG_UINT id;
- wins_owner->max_version=((SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_HIGH))<<32 |
- (SMB_BIG_UINT)tdb_fetch_int32(tdb, INFO_ID_LOW);
-
- tdb_close(tdb);
+ winsdb_open(NULL,False);
+ winsdb_get_global_id(NULL,&id);
+ winsdb_close(NULL);
+
+ wins_owner->max_version=id;
}
/****************************************************************************
@@ -351,7 +338,7 @@ static void receive_version_number_map_t
q->rep.avmt_rep.partner_count ,inet_ntoa(q->rep.avmt_rep.initiating_wins_server)));
DEBUG(5,("real peer is: %s\n", peer));
- for (i=0; global_wins_table[0][i].address.s_addr!=addr.s_addr && i<partner_count;i++)
+ for (i=0; !ip_equal(global_wins_table[0][i].address,addr) && i<partner_count;i++)
;
if (i==partner_count) {
@@ -401,7 +388,7 @@ static void receive_version_number_map_t
/****************************************************************************
add an entry to the wins list we'll send.
****************************************************************************/
-static BOOL add_record_to_winsname(WINS_NAME **wins_name, int *max_names, char *name, int type, int wins_flags, int id, struct in_addr *ip_list, int num_ips)
+static BOOL add_record_to_winsname(WINS_NAME **wins_name, int *max_names, struct name_record *namerec, struct in_addr owner_ip, time_t time_now)
{
WINS_NAME *temp_list;
int i;
@@ -413,34 +400,41 @@ static BOOL add_record_to_winsname(WINS_
temp_list[current].name_len=0x11;
- safe_strcpy(temp_list[current].name, name, 15);
+ safe_strcpy(temp_list[current].name, namerec->name.name, 15);
- temp_list[current].type=type;
+ temp_list[current].type=namerec->name.name_type;
temp_list[current].empty=0;
- temp_list[current].name_flag=wins_flags;
+ temp_list[current].name_flag=namerec->data.wins_flags;
- if ( (wins_flags&0x03) == 1 || (wins_flags&0x03)==2)
+ if ( (namerec->data.wins_flags&0x03) == 1 || (namerec->data.wins_flags&0x03)==2)
temp_list[current].group_flag=0x01000000;
else
temp_list[current].group_flag=0x00000000;
- temp_list[current].id=id;
-
- temp_list[current].owner.s_addr=ip_list[0].s_addr;
+ temp_list[current].id=namerec->data.id;
if (temp_list[current].name_flag & 2) {
- temp_list[current].num_ip=num_ips;
- temp_list[current].others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*num_ips);
+ int y;
+ temp_list[current].num_ip = 0;
+ temp_list[current].others=(struct in_addr *)talloc(mem_ctx, sizeof(struct in_addr)*namerec->data.num_addrs);
if (temp_list[current].others==NULL)
return False;
- for (i=0; i<num_ips; i++)
- temp_list[current].others[i].s_addr=ip_list[i].s_addr;
-
- } else
+ for (i=0,y=0; i<namerec->data.num_addrs; i++) {
+ if (ip_equal(namerec->data.addrs[i].owner,owner_ip) &&
+ (((namerec->data.addrs[i].ttl - 60)> time_now)||
+ (namerec->data.addrs[i].ttl == PERMANENT_TTL))){
+ temp_list[current].others[y]=namerec->data.addrs[i].ip;
+ temp_list[current].num_ip++;
+ y++;
+ }
+ }
+ } else {
temp_list[current].num_ip=1;
-
+ temp_list[current].owner=namerec->data.addrs[0].ip;
+ }
+
temp_list[current].foo=0xffffffff;
*wins_name=temp_list;
@@ -457,10 +451,9 @@ static void send_entry_request(GENERIC_P
int i;
time_t time_now = time(NULL);
WINS_OWNER *wins_owner;
- TDB_CONTEXT *tdb;
- TDB_DATA kbuf, dbuf, newkey;
int s_ctx=get_server_assoc(q->header.assoc_ctx);
int num_interfaces = iface_count();
+ struct name_record *namerec;
if (s_ctx==0) {
DEBUG(1, ("send_entry_request: request for a partner not in our table\n"));
@@ -484,97 +477,37 @@ static void send_entry_request(GENERIC_P
for (i=0; i<num_interfaces; i++)
if (ip_equal(wins_owner->address, *iface_n_ip(i))) {
- wins_owner->address=*interpret_addr2("0.0.0.0");
+ wins_owner->address=wins_fake_ip();
break;
}
- tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600);
- if (!tdb) {
- DEBUG(2,("send_entry_request: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) ));
- return;
- }
+ winsdb_open(NULL,False);
- for (kbuf = tdb_firstkey(tdb);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
- pstring name_type, name, ip_str;
- char *p;
- int type = 0;
- int nb_flags;
- int ttl;
- unsigned int num_ips;
- int low, high;
- SMB_BIG_UINT version;
- struct in_addr wins_ip;
- struct in_addr *ip_list;
- int wins_flags;
- int len;
+ while(NT_STATUS_IS_OK(winsdb_get_next_record(NULL,&namerec))) {
- if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0)
+ if (!namerec)
continue;
-
-
- dbuf = tdb_fetch(tdb, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX));
- pstrcpy(name, name_type);
-
- if((p = strchr(name,'#')) != NULL) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd",
- &nb_flags,
- &high,
- &low,
- ip_str,
- &ttl,
- &num_ips,
- &wins_flags);
-
- wins_ip=*interpret_addr2(ip_str);
-
- /* Allocate the space for the ip_list. */
- if((ip_list = (struct in_addr *)talloc(mem_ctx, num_ips * sizeof(struct in_addr))) == NULL) {
- DEBUG(0,("initialise_wins: talloc fail !\n"));
- return;
- }
-
- for (i = 0; i < num_ips; i++) {
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str);
- ip_list[i] = *interpret_addr2(ip_str);
- }
-
- /* add all entries that have 60 seconds or more to live */
- if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
- if(ttl != PERMANENT_TTL)
- ttl -= time_now;
-
- DEBUG( 4, ("send_entry_request: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
-
- /* add the record to the list to send */
- version=((SMB_BIG_UINT)high)<<32 | low;
- if (wins_owner->min_version<=version && wins_owner->max_version>=version &&
- wins_owner->address.s_addr==wins_ip.s_addr) {
- if(!add_record_to_winsname(&r->rep.se_rp.wins_name, &max_names, name, type, wins_flags, version, ip_list, num_ips))
+ /* add all entries that have 60 seconds or more to live */
+ if ((namerec->data.ttl - 60) > time_now || namerec->data.ttl == PERMANENT_TTL) {
+ if(namerec->data.ttl != PERMANENT_TTL)
+ namerec->data.ttl -= time_now;
+
+ if (wins_owner->min_version<=namerec->data.id && wins_owner->max_version>=namerec->data.id &&
+ ip_equal(wins_owner->address,namerec->data.owner)) {
+ if(!add_record_to_winsname(&r->rep.se_rp.wins_name, &max_names, namerec, wins_owner->address, time_now))
return;
max_names++;
}
} else {
- DEBUG(4, ("send_entry_request: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n",
- name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
+
}
}
-
- tdb_close(tdb);
+ winsdb_close(NULL);
+
DEBUG(4,("send_entry_request, sending %d records\n", max_names));
fill_header(r, OPCODE_NON_NBT, s_ctx, MESSAGE_TYPE_REPLICATE);
r->rep.msg_type=MESSAGE_REP_SEND_ENTRIES_REPLY; /* reply */
@@ -607,7 +540,7 @@ static void update_notify_request(GENERI
get_our_last_id(&global_wins_table[0][0]);
for (i=0; i<partner_count; i++) {
- if (global_wins_table[0][i].address.s_addr==u->initiating_wins_server.s_addr) {
+ if (ip_equal(global_wins_table[0][i].address,u->initiating_wins_server)) {
DEBUG(5,("update_notify_request: found initiator at index %d\n", i));
break;
}
@@ -721,13 +654,13 @@ static void send_entry_reply(GENERIC_PAC
record.wins_flags=q->rep.se_rp.wins_name[k].name_flag&0x00ff;
record.num_ips=q->rep.se_rp.wins_name[k].num_ip;
- record.wins_ip.s_addr=server.s_addr;
+ record.owner = server;
if (record.num_ips==1)
- record.ip[0]=q->rep.se_rp.wins_name[k].owner;
+ record.ips[0]=q->rep.se_rp.wins_name[k].owner;
else
- for (i=0; i<record.num_ips; i++)
- record.ip[i]=q->rep.se_rp.wins_name[k].others[i];
+ for (i=0; i<record.num_ips && i< MAX_WINS_GROUP_IPS; i++)
+ record.ips[i]=q->rep.se_rp.wins_name[k].others[i];
record.nb_flags=0;
More information about the samba-technical
mailing list