don't attempt to answer QFILEINFO/SMB_QUERY_FILE_STREAM_INFO queries -
[samba.git] / source3 / nmbd / nmbd.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    NBT netbios routines and daemon - version 2
5    Copyright (C) Andrew Tridgell 1994-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20    
21    Revision History:
22
23    14 jan 96: lkcl@pires.co.uk
24    added multiple workgroup domain master support
25
26 */
27
28 #include "includes.h"
29
30 extern int DEBUGLEVEL;
31
32 extern pstring debugf;
33 pstring servicesf = CONFIGFILE;
34
35 extern pstring scope;
36
37 int ClientNMB       = -1;
38 int ClientDGRAM     = -1;
39 int global_nmb_port = -1;
40
41 extern pstring myhostname;
42 static pstring host_file;
43 extern pstring global_myname;
44 extern fstring global_myworkgroup;
45 extern char **my_netbios_names;
46
47 extern BOOL global_in_nmbd;
48
49 /* are we running as a daemon ? */
50 static BOOL is_daemon = False;
51
52 /* have we found LanMan clients yet? */
53 BOOL found_lm_clients = False;
54
55 /* what server type are we currently */
56
57 time_t StartupTime = 0;
58
59 extern struct in_addr ipzero;
60
61 /**************************************************************************** **
62   catch a sigterm
63  **************************************************************************** */
64 static void sig_term(int sig)
65 {
66   BlockSignals(True,SIGTERM);
67   
68   DEBUG(0,("Got SIGTERM: going down...\n"));
69   
70   /* Write out wins.dat file if samba is a WINS server */
71   wins_write_database();
72   
73   /* Remove all SELF registered names. */
74   release_my_names();
75   
76   /* Announce all server entries as 0 time-to-live, 0 type. */
77   announce_my_servers_removed();
78
79   /* If there was an async dns child - kill it. */
80   kill_async_dns_child();
81
82   exit(0);
83
84 } /* sig_term */
85
86 /**************************************************************************** **
87  catch a sighup
88  **************************************************************************** */
89 static void sig_hup(int sig)
90 {
91   BlockSignals( True, SIGHUP );
92
93   DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
94
95   write_browse_list( 0, True );
96
97   dump_all_namelists();
98   reload_services( True );
99
100   set_samba_nb_type();
101
102   BlockSignals(False,SIGHUP);
103
104 } /* sig_hup */
105
106 /**************************************************************************** **
107  catch a sigpipe
108  **************************************************************************** */
109 static void sig_pipe(int sig)
110 {
111   BlockSignals( True, SIGPIPE );
112
113   DEBUG( 0, ("Got SIGPIPE\n") );
114   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( "\n");
538 } /* usage */
539
540
541 /**************************************************************************** **
542  main program
543  **************************************************************************** */
544 int main(int argc,char *argv[])
545 {
546   int opt;
547   extern FILE *dbf;
548   extern char *optarg;
549
550   global_nmb_port = NMB_PORT;
551   *host_file = 0;
552   global_in_nmbd = True;
553
554   StartupTime = time(NULL);
555
556   TimeInit();
557
558   pstrcpy( debugf, NMBLOGFILE );
559
560   setup_logging( argv[0], False );
561
562   charset_initialise();
563
564   if(!initialize_password_db())
565     exit(1);
566
567 #ifdef LMHOSTSFILE
568   pstrcpy( 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((void (*)(void *))fault_continue );
579
580   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
581   CatchSignal( 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   CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
591 #endif /* SIGUSR1 */
592
593 #if defined(SIGUSR2)
594   CatchSignal( 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 's':
603           pstrcpy(servicesf,optarg);
604           break;          
605         case 'N':
606         case 'B':
607         case 'I':
608         case 'C':
609         case 'G':
610           DEBUG(0,("Obsolete option '%c' used\n",opt));
611           break;
612         case 'H':
613           pstrcpy(host_file,optarg);
614           break;
615         case 'n':
616           pstrcpy(global_myname,optarg);
617           strupper(global_myname);
618           break;
619         case 'l':
620           slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
621           break;
622         case 'i':
623           pstrcpy(scope,optarg);
624           strupper(scope);
625           break;
626         case 'a':
627           {
628           extern BOOL append_log;
629           append_log = !append_log;
630           }
631           break;
632         case 'D':
633           is_daemon = True;
634           break;
635         case 'd':
636           DEBUGLEVEL = atoi(optarg);
637           break;
638         case 'p':
639           global_nmb_port = atoi(optarg);
640           break;
641         case 'h':
642           usage(argv[0]);
643           exit(0);
644           break;
645         default:
646           if( !is_a_socket(0) )
647           {
648             usage(argv[0]);
649             exit(0);
650           }
651           break;
652         }
653     }
654
655   reopen_logs();
656
657   DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
658   DEBUGADD( 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( global_myworkgroup, lp_workgroup() );
677
678   if (strequal(global_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, ( "Becoming a daemon.\n" ) );
695     become_daemon();
696   }
697
698   if (!directory_exist(lp_lockdir(), NULL)) {
699           mkdir(lp_lockdir(), 0755);
700   }
701
702   pidfile_create("nmbd");
703
704   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
705
706   if ( !open_sockets( is_daemon, global_nmb_port ) )
707     return 1;
708
709   /* Determine all the IP addresses we have. */
710   load_interfaces();
711
712   /* Create an nmbd subnet record for each of the above. */
713   if( False == create_subnets() )
714   {
715     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
716     exit(1);
717   }
718
719   /* Load in any static local names. */ 
720   if ( *host_file )
721   {
722     load_lmhosts_file(host_file);
723     DEBUG(3,("Loaded hosts file\n"));
724   }
725
726   /* If we are acting as a WINS server, initialise data structures. */
727   if( !initialise_wins() )
728   {
729     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
730     exit(1);
731   }
732
733   /* 
734    * Register nmbd primary workgroup and nmbd names on all
735    * the broadcast subnets, and on the WINS server (if specified).
736    * Also initiate the startup of our primary workgroup (start
737    * elections if we are setup as being able to be a local
738    * master browser.
739    */
740
741   if( False == register_my_workgroup_and_names() )
742   {
743     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
744     exit(1);
745   }
746
747   /* We can only take signals in the select. */
748   BlockSignals( True, SIGTERM );
749 #if defined(SIGUSR1)
750   BlockSignals( True, SIGUSR1);
751 #endif /* SIGUSR1 */
752 #if defined(SIGUSR2)
753   BlockSignals( True, SIGUSR2);
754 #endif /* SIGUSR2 */
755
756   process();
757   close_sockets();
758
759   if (dbf)
760     fclose(dbf);
761   return(0);
762 } /* main */
763
764 /* ========================================================================== */