s3: piddir creation fix part 2.
[Samba/gebeck_regimport.git] / source3 / nmbd / nmbd.c
blob52d7ed9e4e7d4a948711214f9c02efc1d86501b0
1 /*
2 Unix SMB/CIFS implementation.
3 NBT netbios routines and daemon - version 2
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 1997-2002
6 Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "popt_common.h"
25 #include "nmbd/nmbd.h"
26 #include "serverid.h"
27 #include "messages.h"
29 int ClientNMB = -1;
30 int ClientDGRAM = -1;
31 int global_nmb_port = -1;
33 extern bool rescan_listen_set;
34 extern bool global_in_nmbd;
36 extern bool override_logfile;
38 /* have we found LanMan clients yet? */
39 bool found_lm_clients = False;
41 /* what server type are we currently */
43 time_t StartupTime = 0;
45 struct event_context *nmbd_event_context(void)
47 return server_event_context();
50 /**************************************************************************** **
51 Handle a SIGTERM in band.
52 **************************************************************************** */
54 static void terminate(struct messaging_context *msg)
56 DEBUG(0,("Got SIGTERM: going down...\n"));
58 /* Write out wins.dat file if samba is a WINS server */
59 wins_write_database(0,False);
61 /* Remove all SELF registered names from WINS */
62 release_wins_names();
64 /* Announce all server entries as 0 time-to-live, 0 type. */
65 announce_my_servers_removed();
67 /* If there was an async dns child - kill it. */
68 kill_async_dns_child();
70 gencache_stabilize();
71 serverid_deregister(messaging_server_id(msg));
73 pidfile_unlink();
75 exit(0);
78 static void nmbd_sig_term_handler(struct tevent_context *ev,
79 struct tevent_signal *se,
80 int signum,
81 int count,
82 void *siginfo,
83 void *private_data)
85 struct messaging_context *msg = talloc_get_type_abort(
86 private_data, struct messaging_context);
88 terminate(msg);
92 handle stdin becoming readable when we are in --foreground mode
94 static void nmbd_stdin_handler(struct tevent_context *ev,
95 struct tevent_fd *fde,
96 uint16_t flags,
97 void *private_data)
99 char c;
100 if (read(0, &c, 1) != 1) {
101 struct messaging_context *msg = talloc_get_type_abort(
102 private_data, struct messaging_context);
104 DEBUG(0,("EOF on stdin\n"));
105 terminate(msg);
109 static bool nmbd_setup_sig_term_handler(struct messaging_context *msg)
111 struct tevent_signal *se;
113 se = tevent_add_signal(nmbd_event_context(),
114 nmbd_event_context(),
115 SIGTERM, 0,
116 nmbd_sig_term_handler,
117 msg);
118 if (!se) {
119 DEBUG(0,("failed to setup SIGTERM handler"));
120 return false;
123 return true;
126 static bool nmbd_setup_stdin_handler(struct messaging_context *msg, bool foreground)
128 if (foreground) {
129 /* if we are running in the foreground then look for
130 EOF on stdin, and exit if it happens. This allows
131 us to die if the parent process dies
133 tevent_add_fd(nmbd_event_context(), nmbd_event_context(), 0, TEVENT_FD_READ, nmbd_stdin_handler, msg);
136 return true;
139 static void msg_reload_nmbd_services(struct messaging_context *msg,
140 void *private_data,
141 uint32_t msg_type,
142 struct server_id server_id,
143 DATA_BLOB *data);
145 static void nmbd_sig_hup_handler(struct tevent_context *ev,
146 struct tevent_signal *se,
147 int signum,
148 int count,
149 void *siginfo,
150 void *private_data)
152 struct messaging_context *msg = talloc_get_type_abort(
153 private_data, struct messaging_context);
155 DEBUG(0,("Got SIGHUP dumping debug info.\n"));
156 msg_reload_nmbd_services(msg, NULL, MSG_SMB_CONF_UPDATED,
157 messaging_server_id(msg), NULL);
160 static bool nmbd_setup_sig_hup_handler(struct messaging_context *msg)
162 struct tevent_signal *se;
164 se = tevent_add_signal(nmbd_event_context(),
165 nmbd_event_context(),
166 SIGHUP, 0,
167 nmbd_sig_hup_handler,
168 msg);
169 if (!se) {
170 DEBUG(0,("failed to setup SIGHUP handler"));
171 return false;
174 return true;
177 /**************************************************************************** **
178 Handle a SHUTDOWN message from smbcontrol.
179 **************************************************************************** */
181 static void nmbd_terminate(struct messaging_context *msg,
182 void *private_data,
183 uint32_t msg_type,
184 struct server_id server_id,
185 DATA_BLOB *data)
187 terminate(msg);
190 /**************************************************************************** **
191 Expire old names from the namelist and server list.
192 **************************************************************************** */
194 static void expire_names_and_servers(time_t t)
196 static time_t lastrun = 0;
198 if ( !lastrun )
199 lastrun = t;
200 if ( t < (lastrun + 5) )
201 return;
202 lastrun = t;
205 * Expire any timed out names on all the broadcast
206 * subnets and those registered with the WINS server.
207 * (nmbd_namelistdb.c)
210 expire_names(t);
213 * Go through all the broadcast subnets and for each
214 * workgroup known on that subnet remove any expired
215 * server names. If a workgroup has an empty serverlist
216 * and has itself timed out then remove the workgroup.
217 * (nmbd_workgroupdb.c)
220 expire_workgroups_and_servers(t);
223 /************************************************************************** **
224 Reload the list of network interfaces.
225 Doesn't return until a network interface is up.
226 ************************************************************************** */
228 static void reload_interfaces(time_t t)
230 static time_t lastt;
231 int n;
232 bool print_waiting_msg = true;
233 struct subnet_record *subrec;
235 if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
236 return;
239 lastt = t;
241 if (!interfaces_changed()) {
242 return;
245 try_again:
247 /* the list of probed interfaces has changed, we may need to add/remove
248 some subnets */
249 load_interfaces();
251 /* find any interfaces that need adding */
252 for (n=iface_count() - 1; n >= 0; n--) {
253 char str[INET6_ADDRSTRLEN];
254 const struct interface *iface = get_interface(n);
255 struct in_addr ip, nmask;
257 if (!iface) {
258 DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
259 continue;
262 /* Ensure we're only dealing with IPv4 here. */
263 if (iface->ip.ss_family != AF_INET) {
264 DEBUG(2,("reload_interfaces: "
265 "ignoring non IPv4 interface.\n"));
266 continue;
269 ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
270 nmask = ((const struct sockaddr_in *)(const void *)
271 &iface->netmask)->sin_addr;
274 * We don't want to add a loopback interface, in case
275 * someone has added 127.0.0.1 for smbd, nmbd needs to
276 * ignore it here. JRA.
279 if (is_loopback_addr((const struct sockaddr *)(const void *)&iface->ip)) {
280 DEBUG(2,("reload_interfaces: Ignoring loopback "
281 "interface %s\n",
282 print_sockaddr(str, sizeof(str), &iface->ip) ));
283 continue;
286 for (subrec=subnetlist; subrec; subrec=subrec->next) {
287 if (ip_equal_v4(ip, subrec->myip) &&
288 ip_equal_v4(nmask, subrec->mask_ip)) {
289 break;
293 if (!subrec) {
294 /* it wasn't found! add it */
295 DEBUG(2,("Found new interface %s\n",
296 print_sockaddr(str,
297 sizeof(str), &iface->ip) ));
298 subrec = make_normal_subnet(iface);
299 if (subrec)
300 register_my_workgroup_one_subnet(subrec);
304 /* find any interfaces that need deleting */
305 for (subrec=subnetlist; subrec; subrec=subrec->next) {
306 for (n=iface_count() - 1; n >= 0; n--) {
307 struct interface *iface = get_interface(n);
308 struct in_addr ip, nmask;
309 if (!iface) {
310 continue;
312 /* Ensure we're only dealing with IPv4 here. */
313 if (iface->ip.ss_family != AF_INET) {
314 DEBUG(2,("reload_interfaces: "
315 "ignoring non IPv4 interface.\n"));
316 continue;
318 ip = ((struct sockaddr_in *)(void *)
319 &iface->ip)->sin_addr;
320 nmask = ((struct sockaddr_in *)(void *)
321 &iface->netmask)->sin_addr;
322 if (ip_equal_v4(ip, subrec->myip) &&
323 ip_equal_v4(nmask, subrec->mask_ip)) {
324 break;
327 if (n == -1) {
328 /* oops, an interface has disapeared. This is
329 tricky, we don't dare actually free the
330 interface as it could be being used, so
331 instead we just wear the memory leak and
332 remove it from the list of interfaces without
333 freeing it */
334 DEBUG(2,("Deleting dead interface %s\n",
335 inet_ntoa(subrec->myip)));
336 close_subnet(subrec);
340 rescan_listen_set = True;
342 /* We need to wait if there are no subnets... */
343 if (FIRST_SUBNET == NULL) {
344 void (*saved_handler)(int);
346 if (print_waiting_msg) {
347 DEBUG(0,("reload_interfaces: "
348 "No subnets to listen to. Waiting..\n"));
349 print_waiting_msg = false;
353 * Whilst we're waiting for an interface, allow SIGTERM to
354 * cause us to exit.
356 saved_handler = CatchSignal(SIGTERM, SIG_DFL);
358 /* We only count IPv4, non-loopback interfaces here. */
359 while (iface_count_v4_nl() == 0) {
360 sleep(5);
361 load_interfaces();
364 CatchSignal(SIGTERM, saved_handler);
367 * We got an interface, go back to blocking term.
370 goto try_again;
374 /**************************************************************************** **
375 Reload the services file.
376 **************************************************************************** */
378 static bool reload_nmbd_services(bool test)
380 bool ret;
382 set_remote_machine_name("nmbd", False);
384 if ( lp_loaded() ) {
385 const char *fname = lp_configfile();
386 if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
387 set_dyn_CONFIGFILE(fname);
388 test = False;
392 if ( test && !lp_file_list_changed() )
393 return(True);
395 ret = lp_load_global(get_dyn_CONFIGFILE());
397 /* perhaps the config filename is now set */
398 if ( !test ) {
399 DEBUG( 3, ( "services not loaded\n" ) );
400 reload_nmbd_services( True );
403 return(ret);
406 /**************************************************************************** **
407 * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
408 **************************************************************************** */
410 static void msg_reload_nmbd_services(struct messaging_context *msg,
411 void *private_data,
412 uint32_t msg_type,
413 struct server_id server_id,
414 DATA_BLOB *data)
416 write_browse_list( 0, True );
417 dump_all_namelists();
418 reload_nmbd_services( True );
419 reopen_logs();
420 reload_interfaces(0);
423 static void msg_nmbd_send_packet(struct messaging_context *msg,
424 void *private_data,
425 uint32_t msg_type,
426 struct server_id src,
427 DATA_BLOB *data)
429 struct packet_struct *p = (struct packet_struct *)data->data;
430 struct subnet_record *subrec;
431 struct sockaddr_storage ss;
432 const struct sockaddr_storage *pss;
433 const struct in_addr *local_ip;
435 DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
437 if (data->length != sizeof(struct packet_struct)) {
438 DEBUG(2, ("Discarding invalid packet length from %u\n",
439 (unsigned int)procid_to_pid(&src)));
440 return;
443 if ((p->packet_type != NMB_PACKET) &&
444 (p->packet_type != DGRAM_PACKET)) {
445 DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
446 (unsigned int)procid_to_pid(&src), p->packet_type));
447 return;
450 in_addr_to_sockaddr_storage(&ss, p->ip);
451 pss = iface_ip((struct sockaddr *)(void *)&ss);
453 if (pss == NULL) {
454 DEBUG(2, ("Could not find ip for packet from %u\n",
455 (unsigned int)procid_to_pid(&src)));
456 return;
459 local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
460 subrec = FIRST_SUBNET;
462 p->recv_fd = -1;
463 p->send_fd = (p->packet_type == NMB_PACKET) ?
464 subrec->nmb_sock : subrec->dgram_sock;
466 for (subrec = FIRST_SUBNET; subrec != NULL;
467 subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
468 if (ip_equal_v4(*local_ip, subrec->myip)) {
469 p->send_fd = (p->packet_type == NMB_PACKET) ?
470 subrec->nmb_sock : subrec->dgram_sock;
471 break;
475 if (p->packet_type == DGRAM_PACKET) {
476 p->port = 138;
477 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
478 p->packet.dgram.header.source_port = 138;
481 send_packet(p);
484 /**************************************************************************** **
485 The main select loop.
486 **************************************************************************** */
488 static void process(struct messaging_context *msg)
490 bool run_election;
492 while( True ) {
493 time_t t = time(NULL);
494 TALLOC_CTX *frame = talloc_stackframe();
497 * Check all broadcast subnets to see if
498 * we need to run an election on any of them.
499 * (nmbd_elections.c)
502 run_election = check_elections();
505 * Read incoming UDP packets.
506 * (nmbd_packets.c)
509 if (listen_for_packets(msg, run_election)) {
510 TALLOC_FREE(frame);
511 return;
515 * Process all incoming packets
516 * read above. This calls the success and
517 * failure functions registered when response
518 * packets arrrive, and also deals with request
519 * packets from other sources.
520 * (nmbd_packets.c)
523 run_packet_queue();
526 * Run any elections - initiate becoming
527 * a local master browser if we have won.
528 * (nmbd_elections.c)
531 run_elections(t);
534 * Send out any broadcast announcements
535 * of our server names. This also announces
536 * the workgroup name if we are a local
537 * master browser.
538 * (nmbd_sendannounce.c)
541 announce_my_server_names(t);
544 * Send out any LanMan broadcast announcements
545 * of our server names.
546 * (nmbd_sendannounce.c)
549 announce_my_lm_server_names(t);
552 * If we are a local master browser, periodically
553 * announce ourselves to the domain master browser.
554 * This also deals with syncronising the domain master
555 * browser server lists with ourselves as a local
556 * master browser.
557 * (nmbd_sendannounce.c)
560 announce_myself_to_domain_master_browser(t);
563 * Fullfill any remote announce requests.
564 * (nmbd_sendannounce.c)
567 announce_remote(t);
570 * Fullfill any remote browse sync announce requests.
571 * (nmbd_sendannounce.c)
574 browse_sync_remote(t);
577 * Scan the broadcast subnets, and WINS client
578 * namelists and refresh any that need refreshing.
579 * (nmbd_mynames.c)
582 refresh_my_names(t);
585 * Scan the subnet namelists and server lists and
586 * expire thos that have timed out.
587 * (nmbd.c)
590 expire_names_and_servers(t);
593 * Write out a snapshot of our current browse list into
594 * the browse.dat file. This is used by smbd to service
595 * incoming NetServerEnum calls - used to synchronise
596 * browse lists over subnets.
597 * (nmbd_serverlistdb.c)
600 write_browse_list(t, False);
603 * If we are a domain master browser, we have a list of
604 * local master browsers we should synchronise browse
605 * lists with (these are added by an incoming local
606 * master browser announcement packet). Expire any of
607 * these that are no longer current, and pull the server
608 * lists from each of these known local master browsers.
609 * (nmbd_browsesync.c)
612 dmb_expire_and_sync_browser_lists(t);
615 * Check that there is a local master browser for our
616 * workgroup for all our broadcast subnets. If one
617 * is not found, start an election (which we ourselves
618 * may or may not participate in, depending on the
619 * setting of the 'local master' parameter.
620 * (nmbd_elections.c)
623 check_master_browser_exists(t);
626 * If we are configured as a logon server, attempt to
627 * register the special NetBIOS names to become such
628 * (WORKGROUP<1c> name) on all broadcast subnets and
629 * with the WINS server (if used). If we are configured
630 * to become a domain master browser, attempt to register
631 * the special NetBIOS name (WORKGROUP<1b> name) to
632 * become such.
633 * (nmbd_become_dmb.c)
636 add_domain_names(t);
639 * If we are a WINS server, do any timer dependent
640 * processing required.
641 * (nmbd_winsserver.c)
644 initiate_wins_processing(t);
647 * If we are a domain master browser, attempt to contact the
648 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
649 * This will only work to a Samba WINS server.
650 * (nmbd_browsesync.c)
653 if (lp_enhanced_browsing())
654 collect_all_workgroup_names_from_wins_server(t);
657 * Go through the response record queue and time out or re-transmit
658 * and expired entries.
659 * (nmbd_packets.c)
662 retransmit_or_expire_response_records(t);
665 * check to see if any remote browse sync child processes have completed
668 sync_check_completion();
671 * regularly sync with any other DMBs we know about
674 if (lp_enhanced_browsing())
675 sync_all_dmbs(t);
677 /* check for new network interfaces */
679 reload_interfaces(t);
681 /* free up temp memory */
682 TALLOC_FREE(frame);
686 /**************************************************************************** **
687 Open the socket communication.
688 **************************************************************************** */
690 static bool open_sockets(bool isdaemon, int port)
692 struct sockaddr_storage ss;
693 const char *sock_addr = lp_socket_address();
696 * The sockets opened here will be used to receive broadcast
697 * packets *only*. Interface specific sockets are opened in
698 * make_subnet() in namedbsubnet.c. Thus we bind to the
699 * address "0.0.0.0". The parameter 'socket address' is
700 * now deprecated.
703 if (!interpret_string_addr(&ss, sock_addr,
704 AI_NUMERICHOST|AI_PASSIVE)) {
705 DEBUG(0,("open_sockets: unable to get socket address "
706 "from string %s", sock_addr));
707 return false;
709 if (ss.ss_family != AF_INET) {
710 DEBUG(0,("open_sockets: unable to use IPv6 socket"
711 "%s in nmbd\n",
712 sock_addr));
713 return false;
716 if (isdaemon) {
717 ClientNMB = open_socket_in(SOCK_DGRAM, port,
718 0, &ss,
719 true);
720 } else {
721 ClientNMB = 0;
724 if (ClientNMB == -1) {
725 return false;
728 ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
729 3, &ss,
730 true);
732 if (ClientDGRAM == -1) {
733 if (ClientNMB != 0) {
734 close(ClientNMB);
736 return false;
739 /* we are never interested in SIGPIPE */
740 BlockSignals(True,SIGPIPE);
742 set_socket_options( ClientNMB, "SO_BROADCAST" );
743 set_socket_options( ClientDGRAM, "SO_BROADCAST" );
745 /* Ensure we're non-blocking. */
746 set_blocking( ClientNMB, False);
747 set_blocking( ClientDGRAM, False);
749 DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
750 return( True );
753 /**************************************************************************** **
754 main program
755 **************************************************************************** */
757 int main(int argc, const char *argv[])
759 bool is_daemon = false;
760 bool opt_interactive = false;
761 bool Fork = true;
762 bool no_process_group = false;
763 bool log_stdout = false;
764 poptContext pc;
765 char *p_lmhosts = NULL;
766 int opt;
767 struct messaging_context *msg;
768 enum {
769 OPT_DAEMON = 1000,
770 OPT_INTERACTIVE,
771 OPT_FORK,
772 OPT_NO_PROCESS_GROUP,
773 OPT_LOG_STDOUT
775 struct poptOption long_options[] = {
776 POPT_AUTOHELP
777 {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
778 {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
779 {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
780 {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
781 {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
782 {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"},
783 {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" },
784 POPT_COMMON_SAMBA
785 { NULL }
787 TALLOC_CTX *frame;
788 NTSTATUS status;
791 * Do this before any other talloc operation
793 talloc_enable_null_tracking();
794 frame = talloc_stackframe();
796 setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);
798 load_case_tables();
800 global_nmb_port = NMB_PORT;
802 pc = poptGetContext("nmbd", argc, argv, long_options, 0);
803 while ((opt = poptGetNextOpt(pc)) != -1) {
804 switch (opt) {
805 case OPT_DAEMON:
806 is_daemon = true;
807 break;
808 case OPT_INTERACTIVE:
809 opt_interactive = true;
810 break;
811 case OPT_FORK:
812 Fork = false;
813 break;
814 case OPT_NO_PROCESS_GROUP:
815 no_process_group = true;
816 break;
817 case OPT_LOG_STDOUT:
818 log_stdout = true;
819 break;
820 default:
821 d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
822 poptBadOption(pc, 0), poptStrerror(opt));
823 poptPrintUsage(pc, stderr, 0);
824 exit(1);
827 poptFreeContext(pc);
829 global_in_nmbd = true;
831 StartupTime = time(NULL);
833 sys_srandom(time(NULL) ^ sys_getpid());
835 if (!override_logfile) {
836 char *lfile = NULL;
837 if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
838 exit(1);
840 lp_set_logfile(lfile);
841 SAFE_FREE(lfile);
844 fault_setup();
845 dump_core_setup("nmbd", lp_logfile());
847 /* POSIX demands that signals are inherited. If the invoking process has
848 * these signals masked, we will have problems, as we won't receive them. */
849 BlockSignals(False, SIGHUP);
850 BlockSignals(False, SIGUSR1);
851 BlockSignals(False, SIGTERM);
853 #if defined(SIGFPE)
854 /* we are never interested in SIGFPE */
855 BlockSignals(True,SIGFPE);
856 #endif
858 /* We no longer use USR2... */
859 #if defined(SIGUSR2)
860 BlockSignals(True, SIGUSR2);
861 #endif
863 if ( opt_interactive ) {
864 Fork = False;
865 log_stdout = True;
868 if ( log_stdout && Fork ) {
869 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
870 exit(1);
873 if (log_stdout) {
874 setup_logging(argv[0], DEBUG_STDOUT);
875 } else {
876 setup_logging( argv[0], DEBUG_FILE);
879 reopen_logs();
881 DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
882 DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
884 if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
885 DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
886 exit(1);
889 msg = messaging_init(NULL, server_event_context());
890 if (msg == NULL) {
891 return 1;
894 if ( !reload_nmbd_services(False) )
895 return(-1);
897 if(!init_names())
898 return -1;
900 reload_nmbd_services( True );
902 if (strequal(lp_workgroup(),"*")) {
903 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
904 exit(1);
907 set_samba_nb_type();
909 if (!is_daemon && !is_a_socket(0)) {
910 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
911 is_daemon = True;
914 if (is_daemon && !opt_interactive) {
915 DEBUG( 2, ( "Becoming a daemon.\n" ) );
916 become_daemon(Fork, no_process_group, log_stdout);
919 #if HAVE_SETPGID
921 * If we're interactive we want to set our own process group for
922 * signal management.
924 if (opt_interactive && !no_process_group)
925 setpgid( (pid_t)0, (pid_t)0 );
926 #endif
928 #ifndef SYNC_DNS
929 /* Setup the async dns. We do it here so it doesn't have all the other
930 stuff initialised and thus chewing memory and sockets */
931 if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
932 start_async_dns(msg);
934 #endif
936 if (!directory_exist(lp_lockdir())) {
937 mkdir(lp_lockdir(), 0755);
940 if (!directory_exist(lp_piddir())) {
941 mkdir(lp_piddir(), 0755);
944 pidfile_create("nmbd");
946 status = reinit_after_fork(msg, nmbd_event_context(),
947 false);
949 if (!NT_STATUS_IS_OK(status)) {
950 DEBUG(0,("reinit_after_fork() failed\n"));
951 exit(1);
954 if (!nmbd_setup_sig_term_handler(msg))
955 exit(1);
956 if (!nmbd_setup_stdin_handler(msg, !Fork))
957 exit(1);
958 if (!nmbd_setup_sig_hup_handler(msg))
959 exit(1);
961 /* get broadcast messages */
963 if (!serverid_register(messaging_server_id(msg),
964 FLAG_MSG_GENERAL |
965 FLAG_MSG_NMBD |
966 FLAG_MSG_DBWRAP)) {
967 DEBUG(1, ("Could not register myself in serverid.tdb\n"));
968 exit(1);
971 messaging_register(msg, NULL, MSG_FORCE_ELECTION,
972 nmbd_message_election);
973 #if 0
974 /* Until winsrepl is done. */
975 messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY,
976 nmbd_wins_new_entry);
977 #endif
978 messaging_register(msg, NULL, MSG_SHUTDOWN,
979 nmbd_terminate);
980 messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED,
981 msg_reload_nmbd_services);
982 messaging_register(msg, NULL, MSG_SEND_PACKET,
983 msg_nmbd_send_packet);
985 TimeInit();
987 DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
989 if ( !open_sockets( is_daemon, global_nmb_port ) ) {
990 kill_async_dns_child();
991 return 1;
994 /* Determine all the IP addresses we have. */
995 load_interfaces();
997 /* Create an nmbd subnet record for each of the above. */
998 if( False == create_subnets() ) {
999 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
1000 kill_async_dns_child();
1001 exit(1);
1004 /* Load in any static local names. */
1005 if (p_lmhosts) {
1006 set_dyn_LMHOSTSFILE(p_lmhosts);
1008 load_lmhosts_file(get_dyn_LMHOSTSFILE());
1009 DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
1011 /* If we are acting as a WINS server, initialise data structures. */
1012 if( !initialise_wins() ) {
1013 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
1014 kill_async_dns_child();
1015 exit(1);
1019 * Register nmbd primary workgroup and nmbd names on all
1020 * the broadcast subnets, and on the WINS server (if specified).
1021 * Also initiate the startup of our primary workgroup (start
1022 * elections if we are setup as being able to be a local
1023 * master browser.
1026 if( False == register_my_workgroup_and_names() ) {
1027 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
1028 kill_async_dns_child();
1029 exit(1);
1032 if (!initialize_nmbd_proxy_logon()) {
1033 DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
1034 kill_async_dns_child();
1035 exit(1);
1038 if (!nmbd_init_packet_server()) {
1039 kill_async_dns_child();
1040 exit(1);
1043 TALLOC_FREE(frame);
1044 process(msg);
1046 kill_async_dns_child();
1047 return(0);