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