I realised that my DMB<->DMB sync code has the property that the
[jra/samba/.git] / source3 / nmbd / nmbd.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int DEBUGLEVEL;
31
32 extern pstring debugf;
33 pstring servicesf = CONFIGFILE;
34
35 extern pstring scope;
36
37 int ClientNMB       = -1;
38 int ClientDGRAM     = -1;
39 int global_nmb_port = -1;
40
41 extern pstring myhostname;
42 static pstring host_file;
43 extern pstring global_myname;
44 extern fstring global_myworkgroup;
45 extern char **my_netbios_names;
46
47 extern BOOL global_in_nmbd;
48
49 /* are we running as a daemon ? */
50 static BOOL is_daemon = False;
51
52 /* have we found LanMan clients yet? */
53 BOOL found_lm_clients = False;
54
55 /* what server type are we currently */
56
57 time_t StartupTime = 0;
58
59 extern struct in_addr ipzero;
60
61 /**************************************************************************** **
62   catch a sigterm
63  **************************************************************************** */
64 static void sig_term(int sig)
65 {
66   BlockSignals(True,SIGTERM);
67   
68   DEBUG(0,("Got SIGTERM: going down...\n"));
69   
70   /* Write out wins.dat file if samba is a WINS server */
71   wins_write_database();
72   
73   /* Remove all SELF registered names. */
74   release_my_names();
75   
76   /* Announce all server entries as 0 time-to-live, 0 type. */
77   announce_my_servers_removed();
78
79   /* If there was an async dns child - kill it. */
80   kill_async_dns_child();
81
82   exit(0);
83
84 } /* sig_term */
85
86 /**************************************************************************** **
87  catch a sighup
88  **************************************************************************** */
89 static void sig_hup(int sig)
90 {
91   BlockSignals( True, SIGHUP );
92
93   DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
94
95   write_browse_list( 0, True );
96
97   dump_all_namelists();
98   reload_services( True );
99
100   set_samba_nb_type();
101
102   BlockSignals(False,SIGHUP);
103
104 } /* sig_hup */
105
106 /**************************************************************************** **
107  catch a sigpipe
108  **************************************************************************** */
109 static void sig_pipe(int sig)
110 {
111   BlockSignals( True, SIGPIPE );
112
113   DEBUG( 0, ("Got SIGPIPE\n") );
114
115   BlockSignals( False, SIGPIPE );
116 } /* sig_pipe */
117
118 #if DUMP_CORE
119 /**************************************************************************** **
120  prepare to dump a core file - carefully!
121  **************************************************************************** */
122 static BOOL dump_core(void)
123 {
124   char *p;
125   pstring dname;
126   pstrcpy( dname, debugf );
127   if ((p=strrchr(dname,'/')))
128     *p=0;
129   pstrcat( dname, "/corefiles" );
130   mkdir( dname, 0700 );
131   sys_chown( dname, getuid(), getgid() );
132   chmod( dname, 0700 );
133   if ( chdir(dname) )
134     return( False );
135   umask( ~(0700) );
136
137 #ifdef HAVE_GETRLIMIT
138 #ifdef RLIMIT_CORE
139   {
140     struct rlimit rlp;
141     getrlimit( RLIMIT_CORE, &rlp );
142     rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
143     setrlimit( RLIMIT_CORE, &rlp );
144     getrlimit( RLIMIT_CORE, &rlp );
145     DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
146   }
147 #endif
148 #endif
149
150
151   DEBUG(0,("Dumping core in %s\n",dname));
152   abort();
153   return( True );
154 } /* dump_core */
155 #endif
156
157
158 /**************************************************************************** **
159  possibly continue after a fault
160  **************************************************************************** */
161 static void fault_continue(void)
162 {
163 #if DUMP_CORE
164   dump_core();
165 #endif
166 } /* fault_continue */
167
168 /**************************************************************************** **
169  expire old names from the namelist and server list
170  **************************************************************************** */
171 static void expire_names_and_servers(time_t t)
172 {
173   static time_t lastrun = 0;
174   
175   if ( !lastrun )
176     lastrun = t;
177   if ( t < (lastrun + 5) )
178     return;
179   lastrun = t;
180
181   /*
182    * Expire any timed out names on all the broadcast
183    * subnets and those registered with the WINS server.
184    * (nmbd_namelistdb.c)
185    */
186   expire_names(t);
187
188   /*
189    * Go through all the broadcast subnets and for each
190    * workgroup known on that subnet remove any expired
191    * server names. If a workgroup has an empty serverlist
192    * and has itself timed out then remove the workgroup.
193    * (nmbd_workgroupdb.c)
194    */
195   expire_workgroups_and_servers(t);
196 } /* expire_names_and_servers */
197
198 /**************************************************************************** **
199   reload the services file
200  **************************************************************************** */
201 BOOL reload_services(BOOL test)
202 {
203   BOOL ret;
204   extern fstring remote_machine;
205
206   fstrcpy( remote_machine, "nmb" );
207
208   if ( lp_loaded() )
209   {
210     pstring fname;
211     pstrcpy( fname,lp_configfile());
212     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
213     {
214       pstrcpy(servicesf,fname);
215       test = False;
216     }
217   }
218
219   if ( test && !lp_file_list_changed() )
220     return(True);
221
222   ret = lp_load( servicesf, True , False, False);
223
224   /* perhaps the config filename is now set */
225   if ( !test )
226   {
227     DEBUG( 3, ( "services not loaded\n" ) );
228     reload_services( True );
229   }
230
231   /* Do a sanity check for a misconfigured nmbd */
232   if( lp_wins_support() && *lp_wins_server() )
233   {
234     DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
235 cannot be set in the smb.conf file. nmbd aborting.\n"));
236     exit(10);
237   }
238
239   return(ret);
240 } /* reload_services */
241
242 /**************************************************************************** **
243  The main select loop.
244  **************************************************************************** */
245 static void process(void)
246 {
247   BOOL run_election;
248
249   while( True )
250   {
251     time_t t = time(NULL);
252
253     /*
254      * Check all broadcast subnets to see if
255      * we need to run an election on any of them.
256      * (nmbd_elections.c)
257      */
258     run_election = check_elections();
259
260     /*
261      * Read incoming UDP packets.
262      * (nmbd_packets.c)
263      */
264     if(listen_for_packets(run_election))
265       return;
266
267     /*
268      * Process all incoming packets
269      * read above. This calls the success and
270      * failure functions registered when response
271      * packets arrrive, and also deals with request
272      * packets from other sources.
273      * (nmbd_packets.c)
274      */
275     run_packet_queue();
276
277     /*
278      * Run any elections - initiate becoming
279      * a local master browser if we have won.
280      * (nmbd_elections.c)
281      */
282     run_elections(t);
283
284     /*
285      * Send out any broadcast announcements
286      * of our server names. This also announces
287      * the workgroup name if we are a local
288      * master browser.
289      * (nmbd_sendannounce.c)
290      */
291     announce_my_server_names(t);
292
293     /*
294      * Send out any LanMan broadcast announcements
295      * of our server names.
296      * (nmbd_sendannounce.c)
297      */
298     announce_my_lm_server_names(t);
299
300     /*
301      * If we are a local master browser, periodically
302      * announce ourselves to the domain master browser.
303      * This also deals with syncronising the domain master
304      * browser server lists with ourselves as a local
305      * master browser.
306      * (nmbd_sendannounce.c)
307      */
308     announce_myself_to_domain_master_browser(t);
309
310     /*
311      * Fullfill any remote announce requests.
312      * (nmbd_sendannounce.c)
313      */
314     announce_remote(t);
315
316     /*
317      * Fullfill any remote browse sync announce requests.
318      * (nmbd_sendannounce.c)
319      */
320     browse_sync_remote(t);
321
322     /*
323      * Scan the broadcast subnets, and WINS client
324      * namelists and refresh any that need refreshing.
325      * (nmbd_mynames.c)
326      */
327     refresh_my_names(t);
328
329     /*
330      * Scan the subnet namelists and server lists and
331      * expire thos that have timed out.
332      * (nmbd.c)
333      */
334     expire_names_and_servers(t);
335
336     /*
337      * Write out a snapshot of our current browse list into
338      * the browse.dat file. This is used by smbd to service
339      * incoming NetServerEnum calls - used to synchronise
340      * browse lists over subnets.
341      * (nmbd_serverlistdb.c)
342      */
343     write_browse_list(t, False);
344
345     /*
346      * If we are a domain master browser, we have a list of
347      * local master browsers we should synchronise browse
348      * lists with (these are added by an incoming local
349      * master browser announcement packet). Expire any of
350      * these that are no longer current, and pull the server
351      * lists from each of these known local master browsers.
352      * (nmbd_browsesync.c)
353      */
354     dmb_expire_and_sync_browser_lists(t);
355
356     /*
357      * Check that there is a local master browser for our
358      * workgroup for all our broadcast subnets. If one
359      * is not found, start an election (which we ourselves
360      * may or may not participate in, depending on the
361      * setting of the 'local master' parameter.
362      * (nmbd_elections.c)
363      */
364     check_master_browser_exists(t);
365
366     /*
367      * If we are configured as a logon server, attempt to
368      * register the special NetBIOS names to become such
369      * (WORKGROUP<1c> name) on all broadcast subnets and
370      * with the WINS server (if used). If we are configured
371      * to become a domain master browser, attempt to register
372      * the special NetBIOS name (WORKGROUP<1b> name) to
373      * become such.
374      * (nmbd_become_dmb.c)
375      */
376     add_domain_names(t);
377
378     /*
379      * If we are a WINS server, do any timer dependent
380      * processing required.
381      * (nmbd_winsserver.c)
382      */
383     initiate_wins_processing(t);
384
385     /*
386      * If we are a domain master browser, attempt to contact the
387      * WINS server to get a list of all known WORKGROUPS/DOMAINS.
388      * This will only work to a Samba WINS server.
389      * (nmbd_browsesync.c)
390      */
391     collect_all_workgroup_names_from_wins_server(t);
392
393     /*
394      * Go through the response record queue and time out or re-transmit
395      * and expired entries.
396      * (nmbd_packets.c)
397      */
398     retransmit_or_expire_response_records(t);
399
400     /*
401      * check to see if any remote browse sync child processes have completed
402      */
403     sync_check_completion();
404
405     /*
406      * regularly sync with any other DMBs we know about 
407      */
408     sync_all_dmbs(t);
409   }
410 } /* process */
411
412
413 /**************************************************************************** **
414  open the socket communication
415  **************************************************************************** */
416 static BOOL open_sockets(BOOL isdaemon, int port)
417 {
418   /* The sockets opened here will be used to receive broadcast
419      packets *only*. Interface specific sockets are opened in
420      make_subnet() in namedbsubnet.c. Thus we bind to the
421      address "0.0.0.0". The parameter 'socket address' is
422      now deprecated.
423    */
424
425   if ( isdaemon )
426     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0);
427   else
428     ClientNMB = 0;
429   
430   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0);
431
432   if ( ClientNMB == -1 )
433     return( False );
434
435   CatchSignal( SIGPIPE, SIGNAL_CAST sig_pipe );
436
437   set_socket_options( ClientNMB,   "SO_BROADCAST" );
438   set_socket_options( ClientDGRAM, "SO_BROADCAST" );
439
440   DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
441   return( True );
442 } /* open_sockets */
443
444
445 /**************************************************************************** **
446  initialise connect, service and file structs
447  **************************************************************************** */
448 static BOOL init_structs(void)
449 {
450   extern fstring local_machine;
451   char *p, *ptr;
452   int namecount;
453   int n;
454   int nodup;
455   pstring nbname;
456
457   if (! *global_myname)
458   {
459     fstrcpy( global_myname, myhostname );
460     p = strchr( global_myname, '.' );
461     if (p)
462       *p = 0;
463   }
464   strupper( global_myname );
465
466   /* Add any NETBIOS name aliases. Ensure that the first entry
467      is equal to global_myname.
468    */
469   /* Work out the max number of netbios aliases that we have */
470   ptr = lp_netbios_aliases();
471   for( namecount=0; next_token(&ptr,nbname,NULL, sizeof(nbname)); namecount++ )
472     ;
473   if ( *global_myname )
474     namecount++;
475
476   /* Allocate space for the netbios aliases */
477   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
478   if( NULL == my_netbios_names )
479   {
480      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
481      return( False );
482   }
483  
484   /* Use the global_myname string first */
485   namecount=0;
486   if ( *global_myname )
487     my_netbios_names[namecount++] = global_myname;
488   
489   ptr = lp_netbios_aliases();
490   while ( next_token( &ptr, nbname, NULL, sizeof(nbname) ) )
491   {
492     strupper( nbname );
493     /* Look for duplicates */
494     nodup=1;
495     for( n=0; n<namecount; n++ )
496     {
497       if( 0 == strcmp( nbname, my_netbios_names[n] ) )
498         nodup=0;
499     }
500     if (nodup)
501       my_netbios_names[namecount++] = strdup( nbname );
502   }
503   
504   /* Check the strdups succeeded. */
505   for( n = 0; n < namecount; n++ )
506     if( NULL == my_netbios_names[n] )
507     {
508       DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
509       return False;
510     }
511   
512   /* Terminate name list */
513   my_netbios_names[namecount++] = NULL;
514   
515   fstrcpy( local_machine, global_myname );
516   trim_string( local_machine, " ", " " );
517   p = strchr( local_machine, ' ' );
518   if (p)
519     *p = 0;
520   strlower( local_machine );
521
522   DEBUG( 5, ("Netbios name list:-\n") );
523   for( n=0; my_netbios_names[n]; n++ )
524     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
525
526   return( True );
527 } /* init_structs */
528
529 /**************************************************************************** **
530  usage on the program
531  **************************************************************************** */
532 static void usage(char *pname)
533 {
534   DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
535
536   printf( "Usage: %s [-n name] [-D] [-p port] [-d debuglevel] ", pname );
537   printf( "[-l log basename]\n" );
538   printf( "Version %s\n", VERSION );
539   printf( "\t-D                    become a daemon\n" );
540   printf( "\t-p port               listen on the specified port\n" );
541   printf( "\t-d debuglevel         set the debuglevel\n" );
542   printf( "\t-l log basename.      Basename for log/debug files\n" );
543   printf( "\t-n netbiosname.       " );
544   printf( "the netbios name to advertise for this host\n");
545   printf( "\t-H hosts file         load a netbios hosts file\n" );
546   printf( "\t-a                    append to log file (default)\n" );
547   printf( "\t-o                    overwrite log file, don't append\n" );
548   printf( "\n");
549 } /* usage */
550
551
552 /**************************************************************************** **
553  main program
554  **************************************************************************** */
555 int main(int argc,char *argv[])
556 {
557   int opt;
558   extern FILE *dbf;
559   extern char *optarg;
560   extern BOOL  append_log;
561
562   append_log = True;  /* Default, override with '-o' option. */
563
564   global_nmb_port = NMB_PORT;
565   *host_file = 0;
566   global_in_nmbd = True;
567
568   StartupTime = time(NULL);
569
570   srandom(time(NULL) ^ getpid());
571
572   TimeInit();
573
574   pstrcpy( debugf, NMBLOGFILE );
575
576   setup_logging( argv[0], False );
577
578   charset_initialise();
579
580   if(!initialize_password_db())
581     exit(1);
582
583 #ifdef LMHOSTSFILE
584   pstrcpy( host_file, LMHOSTSFILE );
585 #endif
586
587   /* this is for people who can't start the program correctly */
588   while (argc > 1 && (*argv[1] != '-'))
589   {
590     argv++;
591     argc--;
592   }
593
594   fault_setup((void (*)(void *))fault_continue );
595
596   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
597   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
598
599   /* Setup the signals that allow the debug log level
600      to by dynamically changed. */
601
602   /* If we are using the malloc debug code we can't use
603      SIGUSR1 and SIGUSR2 to do debug level changes. */
604 #ifndef MEM_MAN
605 #if defined(SIGUSR1)
606   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
607 #endif /* SIGUSR1 */
608
609 #if defined(SIGUSR2)
610   CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
611 #endif /* SIGUSR2 */
612 #endif /* MEM_MAN */
613
614   while( EOF != 
615          (opt = getopt( argc, argv, "aos:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:" )) )
616     {
617       switch (opt)
618         {
619         case 's':
620           pstrcpy(servicesf,optarg);
621           break;          
622         case 'N':
623         case 'B':
624         case 'I':
625         case 'C':
626         case 'G':
627           DEBUG(0,("Obsolete option '%c' used\n",opt));
628           break;
629         case 'H':
630           pstrcpy(host_file,optarg);
631           break;
632         case 'n':
633           pstrcpy(global_myname,optarg);
634           strupper(global_myname);
635           break;
636         case 'l':
637           slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
638           break;
639         case 'i':
640           pstrcpy(scope,optarg);
641           strupper(scope);
642           break;
643         case 'a':
644           append_log = True;
645           break;
646         case 'o':
647           append_log = False;
648           break;
649         case 'D':
650           is_daemon = True;
651           break;
652         case 'd':
653           DEBUGLEVEL = atoi(optarg);
654           break;
655         case 'p':
656           global_nmb_port = atoi(optarg);
657           break;
658         case 'h':
659           usage(argv[0]);
660           exit(0);
661           break;
662         default:
663           if( !is_a_socket(0) )
664           {
665             usage(argv[0]);
666             exit(0);
667           }
668           break;
669         }
670     }
671
672   reopen_logs();
673
674   DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
675   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1997\n" ) );
676
677   if( !get_myname( myhostname, NULL) )
678   {
679     DEBUG( 0, ( "Unable to get my hostname - exiting.\n" ) );
680     return -1;
681   }
682
683   if ( !reload_services(False) )
684     return(-1);
685
686   codepage_initialise(lp_client_code_page());
687
688   if(!init_structs())
689     return -1;
690
691   reload_services( True );
692
693   fstrcpy( global_myworkgroup, lp_workgroup() );
694
695   if (strequal(global_myworkgroup,"*"))
696   {
697     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
698     exit(1);
699   }
700
701   set_samba_nb_type();
702
703   if (!is_daemon && !is_a_socket(0))
704   {
705     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
706     is_daemon = True;
707   }
708   
709   if (is_daemon)
710   {
711     DEBUG( 2, ( "Becoming a daemon.\n" ) );
712     become_daemon();
713   }
714
715   if (!directory_exist(lp_lockdir(), NULL)) {
716           mkdir(lp_lockdir(), 0755);
717   }
718
719   pidfile_create("nmbd");
720
721   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
722
723   if ( !open_sockets( is_daemon, global_nmb_port ) )
724     return 1;
725
726   /* Determine all the IP addresses we have. */
727   load_interfaces();
728
729   /* Create an nmbd subnet record for each of the above. */
730   if( False == create_subnets() )
731   {
732     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
733     exit(1);
734   }
735
736   /* Load in any static local names. */ 
737   if ( *host_file )
738   {
739     load_lmhosts_file(host_file);
740     DEBUG(3,("Loaded hosts file\n"));
741   }
742
743   /* If we are acting as a WINS server, initialise data structures. */
744   if( !initialise_wins() )
745   {
746     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
747     exit(1);
748   }
749
750   /* 
751    * Register nmbd primary workgroup and nmbd names on all
752    * the broadcast subnets, and on the WINS server (if specified).
753    * Also initiate the startup of our primary workgroup (start
754    * elections if we are setup as being able to be a local
755    * master browser.
756    */
757
758   if( False == register_my_workgroup_and_names() )
759   {
760     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
761     exit(1);
762   }
763
764   /* We can only take signals in the select. */
765   BlockSignals( True, SIGTERM );
766 #if defined(SIGUSR1)
767   BlockSignals( True, SIGUSR1);
768 #endif /* SIGUSR1 */
769 #if defined(SIGUSR2)
770   BlockSignals( True, SIGUSR2);
771 #endif /* SIGUSR2 */
772
773   process();
774   close_sockets();
775
776   if (dbf)
777     fclose(dbf);
778   return(0);
779 } /* main */
780
781 /* ========================================================================== */