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