Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1995
+ Copyright (C) Andrew Tridgell 1994-1997
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
*/
#include "includes.h"
-#include "loadparm.h"
extern int DEBUGLEVEL;
extern pstring myhostname;
static pstring host_file;
extern pstring myname;
+extern fstring myworkgroup;
/* are we running as a daemon ? */
static BOOL is_daemon = False;
-/* machine comment for host announcements */
-pstring ServerComment="";
-
/* what server type are we currently */
time_t StartupTime =0;
extern struct in_addr ipzero;
-
/****************************************************************************
-catch a sigterm
-****************************************************************************/
+ catch a sigterm
+ ****************************************************************************/
static int sig_term()
{
- BlockSignals(True);
+ BlockSignals(True,SIGTERM);
DEBUG(0,("Got SIGTERM: going down...\n"));
+ /* write out wins.dat file if samba is a WINS server */
dump_names();
- reload_services(True);
/* remove all samba names, with wins server if necessary. */
remove_my_names();
+ /* announce all server entries as 0 time-to-live, 0 type */
/* XXXX don't care if we never receive a response back... yet */
+ announce_my_servers_removed();
+
/* XXXX other things: if we are a master browser, force an election? */
exit(0);
+ /* Keep compiler happy.. */
+ return 0;
}
****************************************************************************/
static int sig_hup(void)
{
- BlockSignals(True);
+ BlockSignals(True,SIGHUP);
DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
dump_names();
reload_services(True);
- BlockSignals(False);
+ set_samba_nb_type();
+
+ BlockSignals(False,SIGHUP);
#ifndef DONT_REINSTALL_SIG
signal(SIGHUP,SIGNAL_CAST sig_hup);
#endif
****************************************************************************/
static int sig_pipe(void)
{
- BlockSignals(True);
+ BlockSignals(True,SIGPIPE);
DEBUG(0,("Got SIGPIPE\n"));
if (!is_daemon)
exit(1);
- BlockSignals(False);
+ BlockSignals(False,SIGPIPE);
return(0);
}
/*******************************************************************
expire old names from the namelist and server list
******************************************************************/
-static void expire_names_and_servers(void)
+static void expire_names_and_servers(time_t t)
{
static time_t lastrun = 0;
- time_t t = time(NULL);
if (!lastrun) lastrun = t;
if (t < lastrun + 5) return;
reload_services(True);
}
- load_interfaces();
+ /* Do a sanity check for a misconfigured nmbd */
+ if(lp_wins_support() && *lp_wins_server()) {
+ DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
+cannot be set in the smb.conf file. nmbd aborting.\n"));
+ exit(10);
+ }
return(ret);
}
while (!feof(f))
{
+ pstring ip,name,flags,extra;
+ struct subnet_record *d;
+ char *ptr;
+ int count = 0;
+ struct in_addr ipaddr;
+ enum name_source source = LMHOSTS;
+
if (!fgets_slash(line,sizeof(pstring),f)) continue;
if (*line == '#') continue;
- {
- BOOL group=False;
-
- pstring ip,name,mask,flags,extra;
-
- char *ptr;
- int count = 0;
- struct in_addr ipaddr;
- struct in_addr ipmask;
- enum name_source source = LMHOSTS;
-
- strcpy(ip,"");
- strcpy(name,"");
- strcpy(mask,"");
- strcpy(flags,"");
- strcpy(extra,"");
-
- ptr = line;
-
- if (next_token(&ptr,ip ,NULL)) ++count;
- if (next_token(&ptr,name ,NULL)) ++count;
- if (next_token(&ptr,mask ,NULL)) ++count;
- if (next_token(&ptr,flags,NULL)) ++count;
- if (next_token(&ptr,extra,NULL)) ++count;
-
- if (count <= 0) continue;
-
- if (count > 0 && count < 2) {
- DEBUG(0,("Ill formed hosts line [%s]\n",line));
- continue;
- }
-
- /* work out if we need to shuffle the tokens along due to the
- optional subnet mask argument */
-
- if (strchr(mask, 'G') || strchr(mask, 'S') || strchr(mask, 'M')) {
- strcpy(flags, mask );
- /* default action for no subnet mask */
- strcpy(mask, "");
- }
-
- DEBUG(4, ("lmhost entry: %s %s %s %s\n", ip, name, mask, flags));
-
- if (strchr(flags,'G') || strchr(flags,'S'))
- group = True;
-
- if (strchr(flags,'M') && !group) {
- source = SELF;
- strcpy(myname,name);
- }
-
- ipaddr = *interpret_addr2(ip);
- if (*mask)
- ipmask = *interpret_addr2(mask);
- else
- ipmask = *iface_nmask(ipaddr);
-
- if (group) {
- add_subnet_entry(ipaddr, ipmask, name, True);
- } else {
- add_netbios_entry(name,0x20,NB_ACTIVE,0,source,ipaddr,True);
- }
+ strcpy(ip,"");
+ strcpy(name,"");
+ strcpy(flags,"");
+
+ ptr = line;
+
+ if (next_token(&ptr,ip ,NULL)) ++count;
+ if (next_token(&ptr,name ,NULL)) ++count;
+ if (next_token(&ptr,flags,NULL)) ++count;
+ if (next_token(&ptr,extra,NULL)) ++count;
+
+ if (count <= 0) continue;
+
+ if (count > 0 && count < 2) {
+ DEBUG(0,("Ill formed hosts line [%s]\n",line));
+ continue;
+ }
+
+ if (count >= 4) {
+ DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
+ continue;
+ }
+
+ DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
+
+ if (strchr(flags,'G') || strchr(flags,'S')) {
+ DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
+ continue;
+ }
+
+ if (strchr(flags,'M')) {
+ source = SELF;
+ strcpy(myname,name);
}
+
+ ipaddr = *interpret_addr2(ip);
+ d = find_subnet_all(ipaddr);
+ if (d) {
+ add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
+ add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
+ }
}
-
+
fclose(f);
}
listen_for_packets(run_election);
run_packet_queue();
- run_elections();
+ run_elections(t);
- announce_host();
+ announce_host(t);
+ announce_master(t);
+ announce_remote(t);
-#if 0
- /* what was this stuff supposed to do? It sent
- ANN_GetBackupListReq packets which I think should only be
- sent when trying to find out who to browse with */
- announce_backup();
-#endif
+ query_refresh_names(t);
- announce_master();
-
- expire_names_and_servers();
- expire_netbios_response_entries(t-10);
+ expire_names_and_servers(t);
+ expire_netbios_response_entries(t);
refresh_my_names(t);
- write_browse_list();
- do_browser_lists();
- check_master_browser();
+ write_browse_list(t);
+ do_browser_lists(t);
+ check_master_browser(t);
+ add_domain_names(t);
}
}
}
if (isdaemon)
- ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
+ ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
else
ClientNMB = 0;
- ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
+ ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
if (ClientNMB == -1)
return(False);
****************************************************************************/
static BOOL init_structs()
{
- if (!get_myname(myhostname,NULL))
- return(False);
+ extern fstring local_machine;
+ char *p;
if (! *myname) {
- char *p;
strcpy(myname,myhostname);
p = strchr(myname,'.');
if (p) *p = 0;
}
+ strupper(myname);
+
+ strcpy(local_machine,myname);
+ trim_string(local_machine," "," ");
+ p = strchr(local_machine,' ');
+ if (p) *p = 0;
+ strlower(local_machine);
return True;
}
{
DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
- printf("Usage: %s [-n name] [-B bcast address] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
+ printf("Usage: %s [-n name] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
printf("Version %s\n",VERSION);
printf("\t-D become a daemon\n");
printf("\t-p port listen on the specified port\n");
printf("\t-d debuglevel set the debuglevel\n");
printf("\t-l log basename. Basename for log/debug files\n");
printf("\t-n netbiosname. the netbios name to advertise for this host\n");
- printf("\t-B broadcast address the address to use for broadcasts\n");
- printf("\t-N netmask the netmask to use for subnet determination\n");
printf("\t-H hosts file load a netbios hosts file\n");
- printf("\t-G group name add a group name to be part of\n");
- printf("\t-I ip-address override the IP address\n");
- printf("\t-C comment sets the machine comment that appears in browse lists\n");
printf("\n");
}
int opt;
extern FILE *dbf;
extern char *optarg;
- fstring group;
+ char pidFile[100] = { 0 };
- *group = 0;
*host_file = 0;
StartupTime = time(NULL);
fault_setup(fault_continue);
- signal(SIGHUP,SIGNAL_CAST sig_hup);
+ signal(SIGHUP ,SIGNAL_CAST sig_hup);
signal(SIGTERM,SIGNAL_CAST sig_term);
- while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:")) != EOF)
+ while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:")) != EOF)
{
switch (opt)
{
+ case 'f':
+ strncpy(pidFile, optarg, sizeof(pidFile));
+ break;
case 's':
strcpy(servicesf,optarg);
- break;
+ break;
+ case 'N':
+ case 'B':
+ case 'I':
case 'C':
- strcpy(ServerComment,optarg);
- break;
case 'G':
- strcpy(group,optarg);
+ DEBUG(0,("Obsolete option '%c' used\n",opt));
break;
case 'H':
strcpy(host_file,optarg);
break;
- case 'I':
- iface_set_default(optarg,NULL,NULL);
- break;
- case 'B':
- iface_set_default(NULL,optarg,NULL);
- break;
- case 'N':
- iface_set_default(NULL,NULL,optarg);
- break;
case 'n':
strcpy(myname,optarg);
+ strupper(myname);
break;
case 'l':
sprintf(debugf,"%s.nmb",optarg);
}
DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
- DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
+ DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
- init_structs();
+ get_myname(myhostname,NULL);
if (!reload_services(False))
return(-1);
- if (*group)
- add_my_domains(group);
+ codepage_initialise(lp_client_code_page());
+
+ init_structs();
+
+ reload_services(True);
+
+ strcpy(myworkgroup, lp_workgroup());
+
+ if (strequal(myworkgroup,"*")) {
+ DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
+ exit(1);
+ }
+
+ set_samba_nb_type();
if (!is_daemon && !is_a_socket(0)) {
DEBUG(0,("standard input is not a socket, assuming -D option\n"));
become_daemon();
}
+ if (*pidFile)
+ {
+ int fd;
+ char buf[20];
+
+ if ((fd = open(pidFile,
+ O_NONBLOCK | O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
+ {
+ DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
+ exit(1);
+ }
+ if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
+ {
+ DEBUG(0,("ERROR: nmbd is already running\n"));
+ exit(1);
+ }
+ sprintf(buf, "%u\n", (unsigned int) getpid());
+ if (write(fd, buf, strlen(buf)) < 0)
+ {
+ DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
+ exit(1);
+ }
+ /* Leave pid file open & locked for the duration... */
+ }
+
+
DEBUG(3,("Opening sockets %d\n", port));
if (!open_sockets(is_daemon,port)) return 1;
- if (*host_file) {
- load_hosts_file(host_file);
- DEBUG(3,("Loaded hosts file\n"));
- }
-
- if (!*ServerComment)
- strcpy(ServerComment,"Samba %v");
- string_sub(ServerComment,"%v",VERSION);
- string_sub(ServerComment,"%h",myhostname);
+ load_interfaces();
+ add_my_subnets(myworkgroup);
add_my_names();
- add_my_domains(lp_workgroup());
DEBUG(3,("Checked names\n"));
- write_browse_list();
+ load_netbios_names();
+
+ DEBUG(3,("Loaded names\n"));
+
+ if (*host_file) {
+ load_hosts_file(host_file);
+ DEBUG(3,("Loaded hosts file\n"));
+ }
+
+ write_browse_list(time(NULL));
DEBUG(3,("Dumped names\n"));
+ /* We can only take sigterm signals in the select. */
+ BlockSignals(True,SIGTERM);
process();
close_sockets();