diff options
author | Samba Release Account <samba-bugs@samba.org> | 1996-07-10 18:48:49 +0000 |
---|---|---|
committer | Samba Release Account <samba-bugs@samba.org> | 1996-07-10 18:48:49 +0000 |
commit | e5a0619c2839d45b00446c3af3f30599f3f3c5fa (patch) | |
tree | e4f788fae8109e372f55ecc53a40a19740655cc8 /source3/namedb.c | |
parent | 9d59ce1d5715f64105643b01aea8b5b9cba8d5a2 (diff) | |
download | samba-e5a0619c2839d45b00446c3af3f30599f3f3c5fa.tar.gz samba-e5a0619c2839d45b00446c3af3f30599f3f3c5fa.tar.bz2 samba-e5a0619c2839d45b00446c3af3f30599f3f3c5fa.zip |
updated docs to match code mods from last two or three updates. done
some more commenting of code to match docs.
sorted some bugs.
ipc BOOL domains was uninitialised.
lkcl
(This used to be commit cb43ce7bc08fa43a6ce49e0937f13afec5dce67b)
Diffstat (limited to 'source3/namedb.c')
-rw-r--r-- | source3/namedb.c | 707 |
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); - } - } -} - |