summaryrefslogtreecommitdiff
path: root/source3/namedb.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/namedb.c')
-rw-r--r--source3/namedb.c707
1 files changed, 0 insertions, 707 deletions
diff --git a/source3/namedb.c b/source3/namedb.c
deleted file mode 100644
index 96f64393c7..0000000000
--- a/source3/namedb.c
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1995
-
- 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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-#include "smb.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-
-extern time_t StartupTime;
-extern pstring myname;
-extern pstring scope;
-
-extern struct in_addr ipgrp;
-extern struct in_addr ipzero;
-
-/* local interfaces structure */
-extern struct interface *local_interfaces;
-
-/* remote interfaces structure */
-extern struct interface *remote_interfaces;
-
-/* this is our domain/workgroup/server database */
-struct subnet_record *subnetlist = NULL;
-
-static BOOL updatedlists = True;
-int updatecount=0;
-
-int workgroup_count = 0; /* unique index key: one for each workgroup */
-
-/* what server type are we currently */
-
-#define DFLT_SERVER_TYPE (SV_TYPE_WORKSTATION | SV_TYPE_SERVER | \
- SV_TYPE_TIME_SOURCE | SV_TYPE_SERVER_UNIX | \
- SV_TYPE_PRINTQ_SERVER | SV_TYPE_POTENTIAL_BROWSER)
-
-
-/****************************************************************************
- add a workgroup into the domain list
- **************************************************************************/
-static void add_workgroup(struct work_record *work, struct subnet_record *d)
-{
- struct work_record *w2;
-
- if (!work || !d) return;
-
- if (!d->workgrouplist)
- {
- d->workgrouplist = work;
- work->prev = NULL;
- work->next = NULL;
- return;
- }
-
- for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
-
- w2->next = work;
- work->next = NULL;
- work->prev = w2;
-}
-
-
-/****************************************************************************
- create a blank workgroup
- **************************************************************************/
-static struct work_record *make_workgroup(char *name)
-{
- struct work_record *work;
- struct subnet_record *d;
- int t = -1;
-
- if (!name || !name[0]) return NULL;
-
- work = (struct work_record *)malloc(sizeof(*work));
- if (!work) return(NULL);
-
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- work->serverlist = NULL;
-
- work->ServerType = DFLT_SERVER_TYPE;
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->needelection = False;
- work->needannounce = True;
- work->state = MST_NONE;
-
- /* make sure all token representations of workgroups are unique */
-
- for (d = subnetlist; d && t == -1; d = d->next)
- {
- struct work_record *w;
- for (w = d->workgrouplist; w && t == -1; w = w->next)
- {
- if (strequal(w->work_group, work->work_group)) t = w->token;
- }
- }
-
- if (t == -1)
- {
- work->token = ++workgroup_count;
- }
- else
- {
- work->token = t;
- }
-
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST<<1)|(ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master()) {
- work->ElectionCriterion |= 0x80;
- }
-
- return work;
-}
-
-
-/*******************************************************************
- expire old servers in the serverlist
- time of -1 indicates everybody dies
- ******************************************************************/
-void remove_old_servers(struct work_record *work, time_t t)
-{
- struct server_record *s;
- struct server_record *nexts;
-
- /* expire old entries in the serverlist */
- for (s = work->serverlist; s; s = nexts)
- {
- if (t == -1 || (s->death_time && s->death_time < t))
- {
- DEBUG(3,("Removing dead server %s\n",s->serv.name));
- updatedlists = True;
- nexts = s->next;
-
- if (s->prev) s->prev->next = s->next;
- if (s->next) s->next->prev = s->prev;
-
- if (work->serverlist == s)
- work->serverlist = s->next;
-
- free(s);
- }
- else
- {
- nexts = s->next;
- }
- }
-}
-
-
-/*******************************************************************
- remove workgroups
- ******************************************************************/
-struct work_record *remove_workgroup(struct subnet_record *d,
- struct work_record *work)
-{
- struct work_record *ret_work = NULL;
-
- if (!d || !work) return NULL;
-
- DEBUG(3,("Removing old workgroup %s\n", work->work_group));
-
- remove_old_servers(work, -1);
-
- ret_work = work->next;
-
- if (work->prev) work->prev->next = work->next;
- if (work->next) work->next->prev = work->prev;
-
- if (d->workgrouplist == work) d->workgrouplist = work->next;
-
- free(work);
-
- return ret_work;
-}
-
-
-/****************************************************************************
- add a domain into the list
- **************************************************************************/
-static void add_subnet(struct subnet_record *d)
-{
- struct subnet_record *d2;
-
- if (!subnetlist)
- {
- subnetlist = d;
- d->prev = NULL;
- d->next = NULL;
- return;
- }
-
- for (d2 = subnetlist; d2->next; d2 = d2->next);
-
- d2->next = d;
- d->next = NULL;
- d->prev = d2;
-}
-
-/***************************************************************************
- add a server into the list
- **************************************************************************/
-static void add_server(struct work_record *work,struct server_record *s)
-{
- struct server_record *s2;
-
- if (!work->serverlist) {
- work->serverlist = s;
- s->prev = NULL;
- s->next = NULL;
- return;
- }
-
- for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
-
- s2->next = s;
- s->next = NULL;
- s->prev = s2;
-}
-
-
-/****************************************************************************
- find a workgroup in the workgrouplist
- only create it if the domain allows it, or the parameter 'add' insists
- that it get created/added anyway. this allows us to force entries in
- lmhosts file to be added.
- **************************************************************************/
-struct work_record *find_workgroupstruct(struct subnet_record *d,
- fstring name, BOOL add)
-{
- struct work_record *ret, *work;
-
- if (!d) return NULL;
-
- DEBUG(4, ("workgroup search for %s: ", name));
-
- if (strequal(name, "*"))
- {
- DEBUG(2,("add any workgroups: initiating browser search on %s\n",
- inet_ntoa(d->bcast_ip)));
- queue_netbios_pkt_wins(d,ClientNMB,NMB_QUERY, NAME_QUERY_FIND_MST,
- MSBROWSE,0x1,0,0,
- True,False, d->bcast_ip, d->bcast_ip);
- return NULL;
- }
-
- for (ret = d->workgrouplist; ret; ret = ret->next) {
- if (!strcmp(ret->work_group,name)) {
- DEBUG(4, ("found\n"));
- return(ret);
- }
- }
-
- if (!add) {
- DEBUG(4, ("not found\n"));
- return NULL;
- }
-
- DEBUG(4,("not found: creating\n"));
-
- if ((work = make_workgroup(name)))
- {
- if (lp_preferred_master() &&
- strequal(lp_workgroup(), name) &&
- d->my_interface)
- {
- DEBUG(3, ("preferred master startup for %s\n", work->work_group));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
- if (!d->my_interface)
- {
- work->needelection = False;
- }
- add_workgroup(work, d);
- return(work);
- }
- return NULL;
-}
-
-/****************************************************************************
- find a subnet in the subnetlist
- **************************************************************************/
-struct subnet_record *find_subnet(struct in_addr bcast_ip)
-{
- struct subnet_record *d;
- struct in_addr wins_ip = ipgrp;
-
- /* search through subnet list for broadcast/netmask that matches
- the source ip address. a subnet 255.255.255.255 represents the
- WINS list. */
-
- for (d = subnetlist; d; d = d->next)
- {
- if (ip_equal(bcast_ip, wins_ip))
- {
- if (ip_equal(bcast_ip, d->bcast_ip))
- {
- return d;
- }
- }
- else if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
- {
- return(d);
- }
- }
-
- return (NULL);
-}
-
-
-/****************************************************************************
- dump a copy of the workgroup/domain database
- **************************************************************************/
-void dump_workgroups(void)
-{
- struct subnet_record *d;
-
- for (d = subnetlist; d; d = d->next)
- {
- if (d->workgrouplist)
- {
- struct work_record *work;
-
- DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
- DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
- if (work->serverlist)
- {
- struct server_record *s;
- for (s = work->serverlist; s; s = s->next)
- {
- DEBUG(4,("\t\t%s %8x (%s)\n",
- s->serv.name, s->serv.type, s->serv.comment));
- }
- }
- }
- }
- }
-}
-
-/****************************************************************************
- create a domain entry
- ****************************************************************************/
-static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr mask_ip)
-{
- struct subnet_record *d;
- d = (struct subnet_record *)malloc(sizeof(*d));
-
- if (!d) return(NULL);
-
- bzero((char *)d,sizeof(*d));
-
- DEBUG(4, ("making domain %s ", inet_ntoa(bcast_ip)));
- DEBUG(4, ("%s\n", inet_ntoa(mask_ip)));
-
- d->bcast_ip = bcast_ip;
- d->mask_ip = mask_ip;
- d->workgrouplist = NULL;
- d->my_interface = False; /* True iff the interface is on the samba host */
-
- add_subnet(d);
-
- return d;
-}
-
-
-/****************************************************************************
- add the remote interfaces from lp_remote_interfaces() and lp_interfaces()
- to the netbios subnet database.
- ****************************************************************************/
-void add_subnet_interfaces(void)
-{
- struct interface *i;
-
- /* loop on all local interfaces */
- for (i = local_interfaces; i; i = i->next)
- {
- /* add the interface into our subnet database */
- if (!find_subnet(i->bcast))
- {
- struct subnet_record *d = make_subnet(i->bcast,i->nmask);
- if (d)
- {
- /* short-cut method to identifying local interfaces */
- d->my_interface = True;
- }
- }
- }
-
- /* loop on all remote interfaces */
- for (i = remote_interfaces; i; i = i->next)
- {
- /* add the interface into our subnet database */
- if (!find_subnet(i->bcast))
- {
- make_subnet(i->bcast,i->nmask);
- }
- }
-
- /* add the pseudo-ip interface for WINS: 255.255.255.255 */
- if (lp_wins_support())
- {
- struct in_addr wins_bcast = ipgrp;
- struct in_addr wins_nmask = ipzero;
- make_subnet(wins_bcast, wins_nmask);
- }
-}
-
-
-/****************************************************************************
- add a domain entry. creates a workgroup, if necessary, and adds the domain
- to the named a workgroup.
- ****************************************************************************/
-struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
- struct in_addr mask_ip,
- char *name, BOOL add, BOOL lmhosts)
-{
- struct subnet_record *d;
-
- /* XXXX andrew: struct in_addr ip appears not to be referenced at all except
- in the DEBUG comment. i assume that the DEBUG comment below actually
- intends to refer to bcast_ip? i don't know.
-
- struct in_addr ip = ipgrp;
-
- */
-
- if (zero_ip(bcast_ip))
- bcast_ip = *iface_bcast(bcast_ip);
-
- /* add the domain into our domain database */
- if ((d = find_subnet(bcast_ip)) ||
- (d = make_subnet(bcast_ip, mask_ip)))
- {
- struct work_record *w = find_workgroupstruct(d, name, add);
- extern pstring ServerComment;
-
- if (!w) return NULL;
-
- /* add WORKGROUP(1e) and WORKGROUP(00) entries into name database
- or register with WINS server, if it's our workgroup */
- if (strequal(lp_workgroup(), name) && d->my_interface)
- {
- add_my_name_entry(d,name,0x1e,NB_ACTIVE|NB_GROUP);
- add_my_name_entry(d,name,0x0 ,NB_ACTIVE|NB_GROUP);
- }
- /* add samba server name to workgroup list */
- if ((strequal(lp_workgroup(), name) && d->my_interface) || lmhosts)
- {
- add_server_entry(d,w,myname,w->ServerType,0,ServerComment,True);
- }
-
- DEBUG(3,("Added domain name entry %s at %s\n", name,inet_ntoa(bcast_ip)));
- return d;
- }
- return NULL;
-}
-
-/****************************************************************************
- remove all samba's server entries
- ****************************************************************************/
-void remove_my_servers(void)
-{
- struct subnet_record *d;
- for (d = subnetlist; d; d = d->next)
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- struct server_record *s;
- for (s = work->serverlist; s; s = s->next)
- {
- if (!strequal(myname,s->serv.name)) continue;
- announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
- }
- }
- }
-}
-
-
-/****************************************************************************
- add a server entry
- ****************************************************************************/
-struct server_record *add_server_entry(struct subnet_record *d,
- struct work_record *work,
- char *name,int servertype,
- int ttl,char *comment,
- BOOL replace)
-{
- BOOL newentry=False;
- struct server_record *s;
-
- if (name[0] == '*')
- {
- return (NULL);
- }
-
- for (s = work->serverlist; s; s = s->next)
- {
- if (strequal(name,s->serv.name)) break;
- }
-
- if (s && !replace)
- {
- DEBUG(4,("Not replacing %s\n",name));
- return(s);
- }
-
- if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
- updatedlists=True;
-
- if (!s)
- {
- newentry = True;
- s = (struct server_record *)malloc(sizeof(*s));
-
- if (!s) return(NULL);
-
- bzero((char *)s,sizeof(*s));
- }
-
-
- if (d->my_interface && strequal(lp_workgroup(),work->work_group))
- {
- if (servertype)
- servertype |= SV_TYPE_LOCAL_LIST_ONLY;
- }
- else
- {
- servertype &= ~SV_TYPE_LOCAL_LIST_ONLY;
- }
-
- /* update the entry */
- StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
- StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
- strupper(s->serv.name);
- s->serv.type = servertype;
- s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
-
- /* for a domain entry, the comment field refers to the server name */
-
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
-
- if (newentry)
- {
- add_server(work, s);
-
- DEBUG(3,("Added "));
- }
- else
- {
- DEBUG(3,("Updated "));
- }
-
- DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
- name,servertype,comment,
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- return(s);
-}
-
-
-/****************************************************************************
- add the default workgroup into my domain
- **************************************************************************/
-void add_my_subnets(char *group)
-{
- struct interface *i;
-
- /* add or find domain on our local subnet, in the default workgroup */
-
- if (*group == '*') return;
-
- /* the coding choice is up to you, andrew: i can see why you don't want
- global access to the local_interfaces structure: so it can't get
- messed up! */
- for (i = local_interfaces; i; i = i->next)
- {
- add_subnet_entry(i->bcast,i->nmask,group, True, False);
- }
-}
-
-
-/*******************************************************************
- write out browse.dat
- ******************************************************************/
-void write_browse_list(void)
-{
- struct subnet_record *d;
-
- pstring fname,fnamenew;
- FILE *f;
-
- if (!updatedlists) return;
-
- dump_names();
- dump_workgroups();
-
- updatedlists = False;
- updatecount++;
-
- strcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,SERVER_LIST);
- strcpy(fnamenew,fname);
- strcat(fnamenew,".");
-
- f = fopen(fnamenew,"w");
-
- if (!f)
- {
- DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- return;
- }
-
- for (d = subnetlist; d ; d = d->next)
- {
- struct work_record *work;
- for (work = d->workgrouplist; work ; work = work->next)
- {
- struct server_record *s;
- for (s = work->serverlist; s ; s = s->next)
- {
- fstring tmp;
-
- /* don't list domains I don't have a master for */
- if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
- {
- continue;
- }
-
- /* output server details, plus what workgroup/domain
- they're in. without the domain information, the
- combined list of all servers in all workgroups gets
- sent to anyone asking about any workgroup! */
-
- sprintf(tmp, "\"%s\"", s->serv.name);
- fprintf(f, "%-25s ", tmp);
- fprintf(f, "%08x ", s->serv.type);
- sprintf(tmp, "\"%s\" ", s->serv.comment);
- fprintf(f, "%-30s", tmp);
- fprintf(f, "\"%s\"\n", work->work_group);
- }
- }
- }
-
- fclose(f);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("Wrote browse list %s\n",fname));
-}
-
-
-/*******************************************************************
- expire old servers in the serverlist
- ******************************************************************/
-void expire_servers(time_t t)
-{
- struct subnet_record *d;
-
- for (d = subnetlist ; d ; d = d->next)
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- remove_old_servers(work, t);
- }
- }
-}
-