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