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