WINSEDIT.C
Stefan (metze) Metzmacher
metze at metzemix.de
Thu May 1 07:33:17 GMT 2003
Sorry, I missed the file :-)
Hi Jan,Volker
here is the start of the winsedit tool.
It would be cool if someone can finish it,
because I'm busy with the vfs interface and the quota stuff.
for now it can list all entries form the wins_test.tdb.
(We don't want to destroy the wins.tdb :-)
A nice feature would be if it's possible to specify the location of the
wins.tdb
e.g. winsedit -l -f wins2-tdb
Please note:
When the winsedit tool will be able to edit entries in the wins.tdb
YOU MUST USE IT WHEN NMBD IS *NOT* RUNNING!!!!
otherwise the information will not be used and overwritten!!!
Because of the current layout of nmbd.
nmbd read's the wins.tdb on start and then holds the a list in memory.
then it flushes all entries to a new wins.tdb file periodicly and delete
the old file!!!
For the winsserver it would be good if we would have a proper interface to
a winsdb backend.
witch would finally allow us to have allternative backends like LDAP.
But with the current nmbd layout it makes REALLY NO SENSE!
metze
-----------------------------------------------------------------------------
Stefan "metze" Metzmacher <metze at metzemix.de>
-------------- next part --------------
/*
Unix SMB/CIFS implementation.
winsdb editing frontend
Copyright (C) Stefan (metze) Metzmacher 2003
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"
#define WINS_LIST "wins_test.tdb"
#define WINS_VERSION 1
static void dump_name_record(struct name_record *rec, BOOL verbose)
{
int i;
if (verbose) {
d_printf("name: %s#%02X\n",rec->name.name,rec->name.name_type);
#ifdef LARGE_SMB_OFF_T
d_printf(" wins flags[%X] unique id[%llu]\n",
rec->data.wins_flags,rec->data.id);
#else
d_printf(" wins flags[%X] unique id[%lu]\n",
rec->data.wins_flags,rec->data.id);
#endif
for (i=0;i<rec->data.num_ips;i++) {
d_printf(" ip: %s",
inet_ntoa(rec->data.ip[i]));
d_printf(" deadtime[%d] refreshtime[%d]",
rec->data.death_time,rec->data.refresh_time);
d_printf(" ownerip[%s]\n",inet_ntoa(rec->data.wins_ip));
}
} else {
d_printf("%s#%02X ",rec->name.name,rec->name.name_type);
for (i=0;i<rec->data.num_ips;i++) {
d_printf(" %s",
inet_ntoa(rec->data.ip[i]));
}
d_printf("\n");
}
}
/****************************************************************************
List all WINS database records.
*****************************************************************************/
BOOL list_wins_records(BOOL verbose)
{
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");
DEBUG(2,("initialise_wins: started\n"));
/* if(!lp_we_are_a_wins_server())
return True;
*/
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;
}
for (kbuf = tdb_firstkey(tdb);
kbuf.dptr;
newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
fstring name_type;
pstring 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);
/* Allocate the space for the ip_list. */
if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
SAFE_FREE(dbuf.dptr);
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);
}
if((namerec=(struct name_record *)malloc(sizeof(struct name_record)))==NULL) {
SAFE_FREE(ip_list);
SAFE_FREE(dbuf.dptr);
DEBUG(0,("initialise_wins: Malloc fail !\n"));
return False;
}
ZERO_STRUCTP(namerec);
safe_strcpy(namerec->name.name,name,16);
namerec->name.name_type = type;
namerec->data.nb_flags = nb_flags;
namerec->data.num_ips = num_ips;
namerec->data.ip = ip_list;
namerec->data.wins_ip = wins_ip;
namerec->data.death_time = ttl;
namerec->data.source = REGISTER_NAME;
dump_name_record(namerec,verbose);
SAFE_FREE(dbuf.dptr);
SAFE_FREE(ip_list);
SAFE_FREE(namerec);
}
tdb_close(tdb);
return True;
}
static BOOL search_record_winsdb(const char *name, uint16 type)
{
TDB_CONTEXT *tdb;
TDB_DATA data, key;
fstring keystr;
fstring name;
fstring 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;
/* set search key */
slprintf(keystr, sizeof(keystr)-1, "%s%s#%02x", ENTRY_PREFIX, name, type);
key.dptr = keystr;
key.dsize = strlen (keystr) + 1;
if (!(tdb = tdb_open_log(tdb_state->tdbsam_location, 0, TDB_DEFAULT, O_RDONLY, 0600))) {
return False;
}
/* get the record */
data = tdb_fetch (pwd_tdb, key);
if (!data.dptr) {
DEBUG(0, (" Error: %s\n", tdb_errorstr(pwd_tdb)));
tdb_close (tdb);
return False;
}
fstrcpy(name, kbuf.dptr+strlen(ENTRY_PREFIX));
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 *)malloc( num_ips * sizeof(struct in_addr))) == NULL) {
SAFE_FREE(dbuf.dptr);
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);
}
if((namerec=(struct name_record *)malloc(sizeof(struct name_record)))==NULL) {
SAFE_FREE(ip_list);
SAFE_FREE(dbuf.dptr);
DEBUG(0,("initialise_wins: Malloc fail !\n"));
return False;
}
ZERO_STRUCTP(namerec);
safe_strcpy(namerec->name.name,name,16);
namerec->name.name_type = type;
namerec->data.nb_flags = nb_flags;
namerec->data.num_ips = num_ips;
namerec->data.ip = ip_list;
namerec->data.wins_ip = wins_ip;
namerec->data.death_time = ttl;
namerec->data.source = REGISTER_NAME;
dump_name_record(namerec,verbose);
SAFE_FREE(dbuf.dptr);
SAFE_FREE(ip_list);
SAFE_FREE(namerec);
tdb_close(tdb);
return True;
}
int main (int argc, const char **argv)
{
int opt;
BOOL static_entry=True;
BOOL default_times=False;
BOOL verbose=False;
poptContext pc;
struct poptOption long_options[] = {
POPT_AUTOHELP
{"create", 'c', POPT_ARG_STRING, NULL, 0, "create/change record", "NAME"},
{"add", 'a', POPT_ARG_STRING, NULL, 0, "an alias for create", "NAME:IPADDRESS"},
{"delete", 'x', POPT_ARG_STRING, NULL, 0, "delete record", "NAME:IPADDRESS"},
{"list", 'l', POPT_ARG_STRING, NULL, 0, "list all record", "[NAME]"},
{"UNIQUE", 'U', POPT_ARG_STRING, NULL, 0, "unique name", "NAMETYPES"},
{"GROUP", 'G', POPT_ARG_STRING, NULL, 0, "group name", "NAMETYPES"},
{"wins-server", 'T', POPT_ARG_STRING, NULL, 0, "target wins server", "IPADDRESS"},
{"static", 'S', POPT_ARG_NONE, &static_entry, True, "record don't expire", NULL},
{"default-times",'D',POPT_ARG_NONE, &default_times, False, "default times for death and refresh time", NULL},
/* This parameter can be added when we have a better
database format, witch will store all information
to make wins replication completely working.
--metze
{"death-time", 't', POPT_ARG_STRING, NULL, 0, "death time", "TIME"},
{"refresh-time",'r', POPT_ARG_STRING, NULL, 0, "refresh time", "TIME"},
*/ {"verbose", 'v', POPT_ARG_NONE, &verbose, False, "be verbose", NULL},
POPT_COMMON_SAMBA
POPT_TABLEEND
};
setup_logging("winsedit", True);
pc = poptGetContext(NULL, argc, argv, long_options,
POPT_CONTEXT_KEEP_FIRST);
while((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'c':
case 'a':
break;
case 'x':
break;
case 'l':
break;
case 'T':
break;
/*
case 't':
break;
case 'r':
break;
*/ default:
poptPrintHelp(pc, stderr, 0);
exit(1);
}
}
poptGetArg(pc); /* Drop argv[0], the program name */
if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n", dyn_CONFIGFILE);
exit(1);
}
if (!init_names())
exit(1);
list_wins_records(verbose);
return 1;
}
More information about the samba-technical
mailing list