2
Unix SMB/CIFS implementation.
3
NBT netbios routines and daemon - version 2
4
Copyright (C) Andrew Tridgell 1994-1998
5
Copyright (C) Jeremy Allison 1997-2002
6
Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 2 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program; if not, write to the Free Software
20
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
int global_nmb_port = -1;
30
extern BOOL rescan_listen_set;
31
extern struct in_addr loopback_ip;
32
extern BOOL global_in_nmbd;
34
extern BOOL override_logfile;
36
/* are we running as a daemon ? */
37
static BOOL is_daemon;
39
/* fork or run in foreground ? */
40
static BOOL Fork = True;
42
/* log to standard output ? */
43
static BOOL log_stdout;
45
/* have we found LanMan clients yet? */
46
BOOL found_lm_clients = False;
48
/* what server type are we currently */
50
time_t StartupTime = 0;
52
/**************************************************************************** **
53
Handle a SIGTERM in band.
54
**************************************************************************** */
56
static void terminate(void)
58
DEBUG(0,("Got SIGTERM: going down...\n"));
60
/* Write out wins.dat file if samba is a WINS server */
61
wins_write_database(0,False);
63
/* Remove all SELF registered names from WINS */
66
/* Announce all server entries as 0 time-to-live, 0 type. */
67
announce_my_servers_removed();
69
/* If there was an async dns child - kill it. */
70
kill_async_dns_child();
75
/**************************************************************************** **
76
Handle a SHUTDOWN message from smbcontrol.
77
**************************************************************************** */
79
static void nmbd_terminate(int msg_type, struct process_id src,
80
void *buf, size_t len)
85
/**************************************************************************** **
86
Catch a SIGTERM signal.
87
**************************************************************************** */
89
static SIG_ATOMIC_T got_sig_term;
91
static void sig_term(int sig)
94
sys_select_signal(SIGTERM);
97
/**************************************************************************** **
98
Catch a SIGHUP signal.
99
**************************************************************************** */
101
static SIG_ATOMIC_T reload_after_sighup;
103
static void sig_hup(int sig)
105
reload_after_sighup = 1;
106
sys_select_signal(SIGHUP);
109
/**************************************************************************** **
110
Possibly continue after a fault.
111
**************************************************************************** */
113
static void fault_continue(void)
120
/**************************************************************************** **
121
Expire old names from the namelist and server list.
122
**************************************************************************** */
124
static void expire_names_and_servers(time_t t)
126
static time_t lastrun = 0;
130
if ( t < (lastrun + 5) )
135
* Expire any timed out names on all the broadcast
136
* subnets and those registered with the WINS server.
137
* (nmbd_namelistdb.c)
143
* Go through all the broadcast subnets and for each
144
* workgroup known on that subnet remove any expired
145
* server names. If a workgroup has an empty serverlist
146
* and has itself timed out then remove the workgroup.
147
* (nmbd_workgroupdb.c)
150
expire_workgroups_and_servers(t);
153
/************************************************************************** **
154
Reload the list of network interfaces.
155
************************************************************************** */
157
static BOOL reload_interfaces(time_t t)
161
struct subnet_record *subrec;
163
if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
166
if (!interfaces_changed()) return False;
168
/* the list of probed interfaces has changed, we may need to add/remove
172
/* find any interfaces that need adding */
173
for (n=iface_count() - 1; n >= 0; n--) {
174
struct interface *iface = get_interface(n);
177
DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
182
* We don't want to add a loopback interface, in case
183
* someone has added 127.0.0.1 for smbd, nmbd needs to
184
* ignore it here. JRA.
187
if (ip_equal(iface->ip, loopback_ip)) {
188
DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
192
for (subrec=subnetlist; subrec; subrec=subrec->next) {
193
if (ip_equal(iface->ip, subrec->myip) &&
194
ip_equal(iface->nmask, subrec->mask_ip)) break;
198
/* it wasn't found! add it */
199
DEBUG(2,("Found new interface %s\n",
200
inet_ntoa(iface->ip)));
201
subrec = make_normal_subnet(iface);
203
register_my_workgroup_one_subnet(subrec);
207
/* find any interfaces that need deleting */
208
for (subrec=subnetlist; subrec; subrec=subrec->next) {
209
for (n=iface_count() - 1; n >= 0; n--) {
210
struct interface *iface = get_interface(n);
211
if (ip_equal(iface->ip, subrec->myip) &&
212
ip_equal(iface->nmask, subrec->mask_ip)) break;
215
/* oops, an interface has disapeared. This is
216
tricky, we don't dare actually free the
217
interface as it could be being used, so
218
instead we just wear the memory leak and
219
remove it from the list of interfaces without
221
DEBUG(2,("Deleting dead interface %s\n",
222
inet_ntoa(subrec->myip)));
223
close_subnet(subrec);
227
rescan_listen_set = True;
229
/* We need to shutdown if there are no subnets... */
230
if (FIRST_SUBNET == NULL) {
231
DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
237
/**************************************************************************** **
238
Reload the services file.
239
**************************************************************************** */
241
static BOOL reload_nmbd_services(BOOL test)
245
set_remote_machine_name("nmbd", False);
249
pstrcpy( fname,lp_configfile());
250
if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
251
pstrcpy(dyn_CONFIGFILE,fname);
256
if ( test && !lp_file_list_changed() )
259
ret = lp_load( dyn_CONFIGFILE, True , False, False, True);
261
/* perhaps the config filename is now set */
263
DEBUG( 3, ( "services not loaded\n" ) );
264
reload_nmbd_services( True );
270
/**************************************************************************** **
271
* React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
272
* We use buf here to return BOOL result to process() when reload_interfaces()
273
* detects that there are no subnets.
274
**************************************************************************** */
276
static void msg_reload_nmbd_services(int msg_type, struct process_id src,
277
void *buf, size_t len)
279
write_browse_list( 0, True );
280
dump_all_namelists();
281
reload_nmbd_services( True );
285
/* We were called from process() */
286
/* If reload_interfaces() returned True */
287
/* we need to shutdown if there are no subnets... */
288
/* pass this info back to process() */
289
*((BOOL*)buf) = reload_interfaces(0);
293
static void msg_nmbd_send_packet(int msg_type, struct process_id src,
294
void *buf, size_t len)
296
struct packet_struct *p = (struct packet_struct *)buf;
297
struct subnet_record *subrec;
298
struct in_addr *local_ip;
300
DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
302
if (len != sizeof(struct packet_struct)) {
303
DEBUG(2, ("Discarding invalid packet length from %d\n",
304
procid_to_pid(&src)));
308
if ((p->packet_type != NMB_PACKET) &&
309
(p->packet_type != DGRAM_PACKET)) {
310
DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
311
procid_to_pid(&src), p->packet_type));
315
local_ip = iface_ip(p->ip);
317
if (local_ip == NULL) {
318
DEBUG(2, ("Could not find ip for packet from %d\n",
319
procid_to_pid(&src)));
323
subrec = FIRST_SUBNET;
325
p->fd = (p->packet_type == NMB_PACKET) ?
326
subrec->nmb_sock : subrec->dgram_sock;
328
for (subrec = FIRST_SUBNET; subrec != NULL;
329
subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
330
if (ip_equal(*local_ip, subrec->myip)) {
331
p->fd = (p->packet_type == NMB_PACKET) ?
332
subrec->nmb_sock : subrec->dgram_sock;
337
if (p->packet_type == DGRAM_PACKET) {
339
p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
340
p->packet.dgram.header.source_port = 138;
346
/**************************************************************************** **
347
The main select loop.
348
**************************************************************************** */
350
static void process(void)
356
time_t t = time(NULL);
358
/* Check for internal messages */
363
* Check all broadcast subnets to see if
364
* we need to run an election on any of them.
368
run_election = check_elections();
371
* Read incoming UDP packets.
375
if(listen_for_packets(run_election))
379
* Handle termination inband.
388
* Process all incoming packets
389
* read above. This calls the success and
390
* failure functions registered when response
391
* packets arrrive, and also deals with request
392
* packets from other sources.
399
* Run any elections - initiate becoming
400
* a local master browser if we have won.
407
* Send out any broadcast announcements
408
* of our server names. This also announces
409
* the workgroup name if we are a local
411
* (nmbd_sendannounce.c)
414
announce_my_server_names(t);
417
* Send out any LanMan broadcast announcements
418
* of our server names.
419
* (nmbd_sendannounce.c)
422
announce_my_lm_server_names(t);
425
* If we are a local master browser, periodically
426
* announce ourselves to the domain master browser.
427
* This also deals with syncronising the domain master
428
* browser server lists with ourselves as a local
430
* (nmbd_sendannounce.c)
433
announce_myself_to_domain_master_browser(t);
436
* Fullfill any remote announce requests.
437
* (nmbd_sendannounce.c)
443
* Fullfill any remote browse sync announce requests.
444
* (nmbd_sendannounce.c)
447
browse_sync_remote(t);
450
* Scan the broadcast subnets, and WINS client
451
* namelists and refresh any that need refreshing.
458
* Scan the subnet namelists and server lists and
459
* expire thos that have timed out.
463
expire_names_and_servers(t);
466
* Write out a snapshot of our current browse list into
467
* the browse.dat file. This is used by smbd to service
468
* incoming NetServerEnum calls - used to synchronise
469
* browse lists over subnets.
470
* (nmbd_serverlistdb.c)
473
write_browse_list(t, False);
476
* If we are a domain master browser, we have a list of
477
* local master browsers we should synchronise browse
478
* lists with (these are added by an incoming local
479
* master browser announcement packet). Expire any of
480
* these that are no longer current, and pull the server
481
* lists from each of these known local master browsers.
482
* (nmbd_browsesync.c)
485
dmb_expire_and_sync_browser_lists(t);
488
* Check that there is a local master browser for our
489
* workgroup for all our broadcast subnets. If one
490
* is not found, start an election (which we ourselves
491
* may or may not participate in, depending on the
492
* setting of the 'local master' parameter.
496
check_master_browser_exists(t);
499
* If we are configured as a logon server, attempt to
500
* register the special NetBIOS names to become such
501
* (WORKGROUP<1c> name) on all broadcast subnets and
502
* with the WINS server (if used). If we are configured
503
* to become a domain master browser, attempt to register
504
* the special NetBIOS name (WORKGROUP<1b> name) to
506
* (nmbd_become_dmb.c)
512
* If we are a WINS server, do any timer dependent
513
* processing required.
514
* (nmbd_winsserver.c)
517
initiate_wins_processing(t);
520
* If we are a domain master browser, attempt to contact the
521
* WINS server to get a list of all known WORKGROUPS/DOMAINS.
522
* This will only work to a Samba WINS server.
523
* (nmbd_browsesync.c)
526
if (lp_enhanced_browsing())
527
collect_all_workgroup_names_from_wins_server(t);
530
* Go through the response record queue and time out or re-transmit
531
* and expired entries.
535
retransmit_or_expire_response_records(t);
538
* check to see if any remote browse sync child processes have completed
541
sync_check_completion();
544
* regularly sync with any other DMBs we know about
547
if (lp_enhanced_browsing())
551
* clear the unexpected packet queue
557
* Reload the services file if we got a sighup.
560
if(reload_after_sighup) {
561
DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
562
msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
563
pid_to_procid(0), (void*) &no_subnets, 0);
566
reload_after_sighup = 0;
569
/* check for new network interfaces */
571
if(reload_interfaces(t))
574
/* free up temp memory */
579
/**************************************************************************** **
580
Open the socket communication.
581
**************************************************************************** */
583
static BOOL open_sockets(BOOL isdaemon, int port)
586
* The sockets opened here will be used to receive broadcast
587
* packets *only*. Interface specific sockets are opened in
588
* make_subnet() in namedbsubnet.c. Thus we bind to the
589
* address "0.0.0.0". The parameter 'socket address' is
594
ClientNMB = open_socket_in(SOCK_DGRAM, port,
595
0, interpret_addr(lp_socket_address()),
600
ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
601
3, interpret_addr(lp_socket_address()),
604
if ( ClientNMB == -1 )
607
/* we are never interested in SIGPIPE */
608
BlockSignals(True,SIGPIPE);
610
set_socket_options( ClientNMB, "SO_BROADCAST" );
611
set_socket_options( ClientDGRAM, "SO_BROADCAST" );
613
/* Ensure we're non-blocking. */
614
set_blocking( ClientNMB, False);
615
set_blocking( ClientDGRAM, False);
617
DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
621
/**************************************************************************** **
623
**************************************************************************** */
624
int main(int argc, const char *argv[])
627
static BOOL opt_interactive;
629
static char *p_lmhosts = dyn_LMHOSTSFILE;
630
static BOOL no_process_group = False;
631
struct poptOption long_options[] = {
633
{"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
634
{"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
635
{"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
636
{"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
637
{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
638
{"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
639
{"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
646
global_nmb_port = NMB_PORT;
648
pc = poptGetContext("nmbd", argc, argv, long_options, 0);
649
while (poptGetNextOpt(pc) != -1) {};
652
global_in_nmbd = True;
654
StartupTime = time(NULL);
656
sys_srandom(time(NULL) ^ sys_getpid());
658
if (!override_logfile) {
659
slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
660
lp_set_logfile(logfile);
663
fault_setup((void (*)(void *))fault_continue );
664
dump_core_setup("nmbd");
666
/* POSIX demands that signals are inherited. If the invoking process has
667
* these signals masked, we will have problems, as we won't receive them. */
668
BlockSignals(False, SIGHUP);
669
BlockSignals(False, SIGUSR1);
670
BlockSignals(False, SIGTERM);
672
CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
673
CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
676
/* we are never interested in SIGFPE */
677
BlockSignals(True,SIGFPE);
680
/* We no longer use USR2... */
682
BlockSignals(True, SIGUSR2);
685
if ( opt_interactive ) {
690
if ( log_stdout && Fork ) {
691
DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
695
setup_logging( argv[0], log_stdout );
699
DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
700
DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
702
if ( !reload_nmbd_services(False) )
708
reload_nmbd_services( True );
710
if (strequal(lp_workgroup(),"*")) {
711
DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
717
if (!is_daemon && !is_a_socket(0)) {
718
DEBUG(0,("standard input is not a socket, assuming -D option\n"));
722
if (is_daemon && !opt_interactive) {
723
DEBUG( 2, ( "Becoming a daemon.\n" ) );
724
become_daemon(Fork, no_process_group);
729
* If we're interactive we want to set our own process group for
732
if (opt_interactive && !no_process_group)
733
setpgid( (pid_t)0, (pid_t)0 );
737
/* Setup the async dns. We do it here so it doesn't have all the other
738
stuff initialised and thus chewing memory and sockets */
739
if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
744
if (!directory_exist(lp_lockdir(), NULL)) {
745
mkdir(lp_lockdir(), 0755);
748
pidfile_create("nmbd");
750
message_register(MSG_FORCE_ELECTION, nmbd_message_election);
752
/* Until winsrepl is done. */
753
message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
755
message_register(MSG_SHUTDOWN, nmbd_terminate);
756
message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
757
message_register(MSG_SEND_PACKET, msg_nmbd_send_packet);
761
DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
763
if ( !open_sockets( is_daemon, global_nmb_port ) ) {
764
kill_async_dns_child();
768
/* Determine all the IP addresses we have. */
771
/* Create an nmbd subnet record for each of the above. */
772
if( False == create_subnets() ) {
773
DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
774
kill_async_dns_child();
778
/* Load in any static local names. */
779
load_lmhosts_file(p_lmhosts);
780
DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));
782
/* If we are acting as a WINS server, initialise data structures. */
783
if( !initialise_wins() ) {
784
DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
785
kill_async_dns_child();
790
* Register nmbd primary workgroup and nmbd names on all
791
* the broadcast subnets, and on the WINS server (if specified).
792
* Also initiate the startup of our primary workgroup (start
793
* elections if we are setup as being able to be a local
797
if( False == register_my_workgroup_and_names() ) {
798
DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
799
kill_async_dns_child();
803
/* We can only take signals in the select. */
804
BlockSignals( True, SIGTERM );
810
kill_async_dns_child();