Line data Source code
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)
7 :
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.
12 :
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.
17 :
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/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "system/filesys.h"
24 : #include "lib/cmdline/cmdline.h"
25 : #include "nmbd/nmbd.h"
26 : #include "serverid.h"
27 : #include "messages.h"
28 : #include "../lib/util/pidfile.h"
29 : #include "util_cluster.h"
30 : #include "lib/gencache.h"
31 : #include "lib/global_contexts.h"
32 : #include "source3/lib/substitute.h"
33 :
34 : int ClientNMB = -1;
35 : int ClientDGRAM = -1;
36 : int global_nmb_port = -1;
37 :
38 : extern bool rescan_listen_set;
39 : extern bool global_in_nmbd;
40 :
41 : /* have we found LanMan clients yet? */
42 : bool found_lm_clients = False;
43 :
44 : /* what server type are we currently */
45 :
46 : time_t StartupTime = 0;
47 :
48 47440 : struct tevent_context *nmbd_event_context(void)
49 : {
50 47440 : return global_event_context();
51 : }
52 :
53 : /**************************************************************************** **
54 : Handle a SIGTERM in band.
55 : **************************************************************************** */
56 :
57 23 : static void terminate(struct messaging_context *msg)
58 : {
59 23 : DEBUG(0,("Got SIGTERM: going down...\n"));
60 :
61 : /* Write out wins.dat file if samba is a WINS server */
62 23 : wins_write_database(0,False);
63 :
64 : /* Remove all SELF registered names from WINS */
65 23 : release_wins_names();
66 :
67 : /* Announce all server entries as 0 time-to-live, 0 type. */
68 23 : announce_my_servers_removed();
69 :
70 : /* If there was an async dns child - kill it. */
71 23 : kill_async_dns_child();
72 :
73 23 : pidfile_unlink(lp_pid_directory(), "nmbd");
74 :
75 23 : exit(0);
76 : }
77 :
78 0 : 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)
84 : {
85 0 : struct messaging_context *msg = talloc_get_type_abort(
86 : private_data, struct messaging_context);
87 :
88 0 : terminate(msg);
89 0 : }
90 :
91 : /*
92 : handle stdin becoming readable when we are in --foreground mode
93 : */
94 23 : static void nmbd_stdin_handler(struct tevent_context *ev,
95 : struct tevent_fd *fde,
96 : uint16_t flags,
97 : void *private_data)
98 : {
99 : char c;
100 23 : if (read(0, &c, 1) != 1) {
101 23 : struct messaging_context *msg = talloc_get_type_abort(
102 : private_data, struct messaging_context);
103 :
104 23 : DEBUG(0,("EOF on stdin\n"));
105 23 : terminate(msg);
106 : }
107 0 : }
108 :
109 23 : static bool nmbd_setup_sig_term_handler(struct messaging_context *msg)
110 : {
111 : struct tevent_signal *se;
112 :
113 23 : se = tevent_add_signal(nmbd_event_context(),
114 : nmbd_event_context(),
115 : SIGTERM, 0,
116 : nmbd_sig_term_handler,
117 : msg);
118 23 : if (!se) {
119 0 : DEBUG(0,("failed to setup SIGTERM handler"));
120 0 : return false;
121 : }
122 :
123 23 : return true;
124 : }
125 :
126 23 : static bool nmbd_setup_stdin_handler(struct messaging_context *msg, bool foreground)
127 : {
128 23 : 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
132 : Only do this on a pipe or socket, no other device.
133 : */
134 : struct stat st;
135 23 : if (fstat(0, &st) != 0) {
136 0 : return false;
137 : }
138 23 : if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
139 23 : tevent_add_fd(nmbd_event_context(),
140 : nmbd_event_context(),
141 : 0,
142 : TEVENT_FD_READ,
143 : nmbd_stdin_handler,
144 : msg);
145 : }
146 : }
147 :
148 23 : return true;
149 : }
150 :
151 : static void msg_reload_nmbd_services(struct messaging_context *msg,
152 : void *private_data,
153 : uint32_t msg_type,
154 : struct server_id server_id,
155 : DATA_BLOB *data);
156 :
157 0 : static void nmbd_sig_hup_handler(struct tevent_context *ev,
158 : struct tevent_signal *se,
159 : int signum,
160 : int count,
161 : void *siginfo,
162 : void *private_data)
163 : {
164 0 : struct messaging_context *msg = talloc_get_type_abort(
165 : private_data, struct messaging_context);
166 :
167 0 : DEBUG(0,("Got SIGHUP dumping debug info.\n"));
168 0 : msg_reload_nmbd_services(msg, NULL, MSG_SMB_CONF_UPDATED,
169 : messaging_server_id(msg), NULL);
170 0 : }
171 :
172 23 : static bool nmbd_setup_sig_hup_handler(struct messaging_context *msg)
173 : {
174 : struct tevent_signal *se;
175 :
176 23 : se = tevent_add_signal(nmbd_event_context(),
177 : nmbd_event_context(),
178 : SIGHUP, 0,
179 : nmbd_sig_hup_handler,
180 : msg);
181 23 : if (!se) {
182 0 : DEBUG(0,("failed to setup SIGHUP handler"));
183 0 : return false;
184 : }
185 :
186 23 : return true;
187 : }
188 :
189 : /**************************************************************************** **
190 : Handle a SHUTDOWN message from smbcontrol.
191 : **************************************************************************** */
192 :
193 0 : static void nmbd_terminate(struct messaging_context *msg,
194 : void *private_data,
195 : uint32_t msg_type,
196 : struct server_id server_id,
197 : DATA_BLOB *data)
198 : {
199 0 : terminate(msg);
200 0 : }
201 :
202 : /**************************************************************************** **
203 : Expire old names from the namelist and server list.
204 : **************************************************************************** */
205 :
206 5884 : static void expire_names_and_servers(time_t t)
207 : {
208 : static time_t lastrun = 0;
209 :
210 5884 : if ( !lastrun )
211 23 : lastrun = t;
212 5884 : if ( t < (lastrun + 5) )
213 5442 : return;
214 442 : lastrun = t;
215 :
216 : /*
217 : * Expire any timed out names on all the broadcast
218 : * subnets and those registered with the WINS server.
219 : * (nmbd_namelistdb.c)
220 : */
221 :
222 442 : expire_names(t);
223 :
224 : /*
225 : * Go through all the broadcast subnets and for each
226 : * workgroup known on that subnet remove any expired
227 : * server names. If a workgroup has an empty serverlist
228 : * and has itself timed out then remove the workgroup.
229 : * (nmbd_workgroupdb.c)
230 : */
231 :
232 442 : expire_workgroups_and_servers(t);
233 : }
234 :
235 : /************************************************************************** **
236 : Reload the list of network interfaces.
237 : Doesn't return until a network interface is up.
238 : ************************************************************************** */
239 :
240 5887 : static void reload_interfaces(time_t t)
241 : {
242 : static time_t lastt;
243 : int n;
244 5887 : bool print_waiting_msg = true;
245 : struct subnet_record *subrec;
246 :
247 5887 : if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
248 5837 : return;
249 : }
250 :
251 50 : lastt = t;
252 :
253 50 : if (!interfaces_changed()) {
254 50 : return;
255 : }
256 :
257 0 : try_again:
258 :
259 : /* the list of probed interfaces has changed, we may need to add/remove
260 : some subnets */
261 0 : load_interfaces();
262 :
263 : /* find any interfaces that need adding */
264 0 : for (n=iface_count() - 1; n >= 0; n--) {
265 : char str[INET6_ADDRSTRLEN];
266 0 : const struct interface *iface = get_interface(n);
267 : struct in_addr ip, nmask;
268 :
269 0 : if (!iface) {
270 0 : DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
271 0 : continue;
272 : }
273 :
274 : /* Ensure we're only dealing with IPv4 here. */
275 0 : if (iface->ip.ss_family != AF_INET) {
276 0 : DEBUG(2,("reload_interfaces: "
277 : "ignoring non IPv4 interface.\n"));
278 0 : continue;
279 : }
280 :
281 0 : ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
282 0 : nmask = ((const struct sockaddr_in *)(const void *)
283 0 : &iface->netmask)->sin_addr;
284 :
285 : /*
286 : * We don't want to add a loopback interface, in case
287 : * someone has added 127.0.0.1 for smbd, nmbd needs to
288 : * ignore it here. JRA.
289 : */
290 :
291 0 : if (is_loopback_addr((const struct sockaddr *)(const void *)&iface->ip)) {
292 0 : DEBUG(2,("reload_interfaces: Ignoring loopback "
293 : "interface %s\n",
294 : print_sockaddr(str, sizeof(str), &iface->ip) ));
295 0 : continue;
296 : }
297 :
298 0 : for (subrec=subnetlist; subrec; subrec=subrec->next) {
299 0 : if (ip_equal_v4(ip, subrec->myip) &&
300 0 : ip_equal_v4(nmask, subrec->mask_ip)) {
301 0 : break;
302 : }
303 : }
304 :
305 0 : if (!subrec) {
306 : /* it wasn't found! add it */
307 0 : DEBUG(2,("Found new interface %s\n",
308 : print_sockaddr(str,
309 : sizeof(str), &iface->ip) ));
310 0 : subrec = make_normal_subnet(iface);
311 0 : if (subrec)
312 0 : register_my_workgroup_one_subnet(subrec);
313 : }
314 : }
315 :
316 : /* find any interfaces that need deleting */
317 0 : for (subrec=subnetlist; subrec; subrec=subrec->next) {
318 0 : for (n=iface_count() - 1; n >= 0; n--) {
319 0 : struct interface *iface = get_interface(n);
320 : struct in_addr ip, nmask;
321 0 : if (!iface) {
322 0 : continue;
323 : }
324 : /* Ensure we're only dealing with IPv4 here. */
325 0 : if (iface->ip.ss_family != AF_INET) {
326 0 : DEBUG(2,("reload_interfaces: "
327 : "ignoring non IPv4 interface.\n"));
328 0 : continue;
329 : }
330 0 : ip = ((struct sockaddr_in *)(void *)
331 0 : &iface->ip)->sin_addr;
332 0 : nmask = ((struct sockaddr_in *)(void *)
333 0 : &iface->netmask)->sin_addr;
334 0 : if (ip_equal_v4(ip, subrec->myip) &&
335 0 : ip_equal_v4(nmask, subrec->mask_ip)) {
336 0 : break;
337 : }
338 : }
339 0 : if (n == -1) {
340 : /* oops, an interface has disappeared. This is
341 : tricky, we don't dare actually free the
342 : interface as it could be being used, so
343 : instead we just wear the memory leak and
344 : remove it from the list of interfaces without
345 : freeing it */
346 0 : DEBUG(2,("Deleting dead interface %s\n",
347 : inet_ntoa(subrec->myip)));
348 0 : close_subnet(subrec);
349 : }
350 : }
351 :
352 0 : rescan_listen_set = True;
353 :
354 : /* We need to wait if there are no subnets... */
355 0 : if (FIRST_SUBNET == NULL) {
356 : void (*saved_handler)(int);
357 :
358 0 : if (print_waiting_msg) {
359 0 : DEBUG(0,("reload_interfaces: "
360 : "No subnets to listen to. Waiting..\n"));
361 0 : print_waiting_msg = false;
362 : }
363 :
364 : /*
365 : * Whilst we're waiting for an interface, allow SIGTERM to
366 : * cause us to exit.
367 : */
368 0 : saved_handler = CatchSignal(SIGTERM, SIG_DFL);
369 :
370 : /* We only count IPv4, non-loopback interfaces here. */
371 0 : while (iface_count_v4_nl() == 0) {
372 0 : usleep(NMBD_WAIT_INTERFACES_TIME_USEC);
373 0 : load_interfaces();
374 : }
375 :
376 0 : CatchSignal(SIGTERM, saved_handler);
377 :
378 : /*
379 : * We got an interface, go back to blocking term.
380 : */
381 :
382 0 : goto try_again;
383 : }
384 : }
385 :
386 : /**************************************************************************** **
387 : Reload the services file.
388 : **************************************************************************** */
389 :
390 72 : static bool reload_nmbd_services(bool test)
391 : {
392 48 : const struct loadparm_substitution *lp_sub =
393 24 : loadparm_s3_global_substitution();
394 : bool ret;
395 :
396 72 : set_remote_machine_name("nmbd", False);
397 :
398 72 : if ( lp_loaded() ) {
399 72 : char *fname = lp_next_configfile(talloc_tos(), lp_sub);
400 72 : if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
401 0 : set_dyn_CONFIGFILE(fname);
402 0 : test = False;
403 : }
404 72 : TALLOC_FREE(fname);
405 : }
406 :
407 72 : if ( test && !lp_file_list_changed() )
408 49 : return(True);
409 :
410 23 : ret = lp_load_global(get_dyn_CONFIGFILE());
411 :
412 : /* perhaps the config filename is now set */
413 23 : if ( !test ) {
414 23 : DEBUG( 3, ( "services not loaded\n" ) );
415 23 : reload_nmbd_services( True );
416 : }
417 :
418 23 : reopen_logs();
419 :
420 23 : return(ret);
421 : }
422 :
423 : /**************************************************************************** **
424 : * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
425 : **************************************************************************** */
426 :
427 3 : static void msg_reload_nmbd_services(struct messaging_context *msg,
428 : void *private_data,
429 : uint32_t msg_type,
430 : struct server_id server_id,
431 : DATA_BLOB *data)
432 : {
433 3 : write_browse_list( 0, True );
434 3 : dump_all_namelists();
435 3 : reload_nmbd_services( True );
436 3 : reopen_logs();
437 3 : reload_interfaces(0);
438 3 : nmbd_init_my_netbios_names();
439 3 : }
440 :
441 2 : static void msg_nmbd_send_packet(struct messaging_context *msg,
442 : void *private_data,
443 : uint32_t msg_type,
444 : struct server_id src,
445 : DATA_BLOB *data)
446 : {
447 2 : struct packet_struct *p = (struct packet_struct *)data->data;
448 : struct subnet_record *subrec;
449 : struct sockaddr_storage ss;
450 : const struct sockaddr_storage *pss;
451 : const struct in_addr *local_ip;
452 :
453 2 : DEBUG(10, ("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)));
454 :
455 2 : if (data->length != sizeof(struct packet_struct)) {
456 0 : DEBUG(2, ("Discarding invalid packet length from %u\n",
457 : (unsigned int)procid_to_pid(&src)));
458 0 : return;
459 : }
460 :
461 4 : if ((p->packet_type != NMB_PACKET) &&
462 2 : (p->packet_type != DGRAM_PACKET)) {
463 0 : DEBUG(2, ("Discarding invalid packet type from %u: %d\n",
464 : (unsigned int)procid_to_pid(&src), p->packet_type));
465 0 : return;
466 : }
467 :
468 2 : in_addr_to_sockaddr_storage(&ss, p->ip);
469 2 : pss = iface_ip((struct sockaddr *)(void *)&ss);
470 :
471 2 : if (pss == NULL) {
472 0 : DEBUG(2, ("Could not find ip for packet from %u\n",
473 : (unsigned int)procid_to_pid(&src)));
474 0 : return;
475 : }
476 :
477 2 : local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
478 2 : subrec = FIRST_SUBNET;
479 :
480 2 : p->recv_fd = -1;
481 4 : p->send_fd = (p->packet_type == NMB_PACKET) ?
482 2 : subrec->nmb_sock : subrec->dgram_sock;
483 :
484 4 : for (subrec = FIRST_SUBNET; subrec != NULL;
485 0 : subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
486 2 : if (ip_equal_v4(*local_ip, subrec->myip)) {
487 4 : p->send_fd = (p->packet_type == NMB_PACKET) ?
488 2 : subrec->nmb_sock : subrec->dgram_sock;
489 2 : break;
490 : }
491 : }
492 :
493 2 : if (p->packet_type == DGRAM_PACKET) {
494 2 : p->port = 138;
495 2 : p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
496 2 : p->packet.dgram.header.source_port = 138;
497 : }
498 :
499 2 : send_packet(p);
500 : }
501 :
502 : /**************************************************************************** **
503 : The main select loop.
504 : **************************************************************************** */
505 :
506 3652 : static void process(struct messaging_context *msg)
507 : {
508 : bool run_election;
509 :
510 5884 : while( True ) {
511 5907 : time_t t = time(NULL);
512 5907 : TALLOC_CTX *frame = talloc_stackframe();
513 :
514 : /*
515 : * Check all broadcast subnets to see if
516 : * we need to run an election on any of them.
517 : * (nmbd_elections.c)
518 : */
519 :
520 5907 : run_election = check_elections();
521 :
522 : /*
523 : * Read incoming UDP packets.
524 : * (nmbd_packets.c)
525 : */
526 :
527 5907 : if (listen_for_packets(msg, run_election)) {
528 0 : TALLOC_FREE(frame);
529 0 : return;
530 : }
531 :
532 : /*
533 : * Process all incoming packets
534 : * read above. This calls the success and
535 : * failure functions registered when response
536 : * packets arrive, and also deals with request
537 : * packets from other sources.
538 : * (nmbd_packets.c)
539 : */
540 :
541 5884 : run_packet_queue();
542 :
543 : /*
544 : * Run any elections - initiate becoming
545 : * a local master browser if we have won.
546 : * (nmbd_elections.c)
547 : */
548 :
549 5884 : run_elections(t);
550 :
551 : /*
552 : * Send out any broadcast announcements
553 : * of our server names. This also announces
554 : * the workgroup name if we are a local
555 : * master browser.
556 : * (nmbd_sendannounce.c)
557 : */
558 :
559 5884 : announce_my_server_names(t);
560 :
561 : /*
562 : * Send out any LanMan broadcast announcements
563 : * of our server names.
564 : * (nmbd_sendannounce.c)
565 : */
566 :
567 5884 : announce_my_lm_server_names(t);
568 :
569 : /*
570 : * If we are a local master browser, periodically
571 : * announce ourselves to the domain master browser.
572 : * This also deals with syncronising the domain master
573 : * browser server lists with ourselves as a local
574 : * master browser.
575 : * (nmbd_sendannounce.c)
576 : */
577 :
578 5884 : announce_myself_to_domain_master_browser(t);
579 :
580 : /*
581 : * Fullfill any remote announce requests.
582 : * (nmbd_sendannounce.c)
583 : */
584 :
585 5884 : announce_remote(t);
586 :
587 : /*
588 : * Fullfill any remote browse sync announce requests.
589 : * (nmbd_sendannounce.c)
590 : */
591 :
592 5884 : browse_sync_remote(t);
593 :
594 : /*
595 : * Scan the broadcast subnets, and WINS client
596 : * namelists and refresh any that need refreshing.
597 : * (nmbd_mynames.c)
598 : */
599 :
600 5884 : refresh_my_names(t);
601 :
602 : /*
603 : * Scan the subnet namelists and server lists and
604 : * expire thos that have timed out.
605 : * (nmbd.c)
606 : */
607 :
608 5884 : expire_names_and_servers(t);
609 :
610 : /*
611 : * Write out a snapshot of our current browse list into
612 : * the browse.dat file. This is used by smbd to service
613 : * incoming NetServerEnum calls - used to synchronise
614 : * browse lists over subnets.
615 : * (nmbd_serverlistdb.c)
616 : */
617 :
618 5884 : write_browse_list(t, False);
619 :
620 : /*
621 : * If we are a domain master browser, we have a list of
622 : * local master browsers we should synchronise browse
623 : * lists with (these are added by an incoming local
624 : * master browser announcement packet). Expire any of
625 : * these that are no longer current, and pull the server
626 : * lists from each of these known local master browsers.
627 : * (nmbd_browsesync.c)
628 : */
629 :
630 5884 : dmb_expire_and_sync_browser_lists(t);
631 :
632 : /*
633 : * Check that there is a local master browser for our
634 : * workgroup for all our broadcast subnets. If one
635 : * is not found, start an election (which we ourselves
636 : * may or may not participate in, depending on the
637 : * setting of the 'local master' parameter.
638 : * (nmbd_elections.c)
639 : */
640 :
641 5884 : check_master_browser_exists(t);
642 :
643 : /*
644 : * If we are configured as a logon server, attempt to
645 : * register the special NetBIOS names to become such
646 : * (WORKGROUP<1c> name) on all broadcast subnets and
647 : * with the WINS server (if used). If we are configured
648 : * to become a domain master browser, attempt to register
649 : * the special NetBIOS name (WORKGROUP<1b> name) to
650 : * become such.
651 : * (nmbd_become_dmb.c)
652 : */
653 :
654 5884 : add_domain_names(t);
655 :
656 : /*
657 : * If we are a WINS server, do any timer dependent
658 : * processing required.
659 : * (nmbd_winsserver.c)
660 : */
661 :
662 5884 : initiate_wins_processing(t);
663 :
664 : /*
665 : * If we are a domain master browser, attempt to contact the
666 : * WINS server to get a list of all known WORKGROUPS/DOMAINS.
667 : * This will only work to a Samba WINS server.
668 : * (nmbd_browsesync.c)
669 : */
670 :
671 5884 : if (lp_enhanced_browsing())
672 5884 : collect_all_workgroup_names_from_wins_server(t);
673 :
674 : /*
675 : * Go through the response record queue and time out or re-transmit
676 : * and expired entries.
677 : * (nmbd_packets.c)
678 : */
679 :
680 5884 : retransmit_or_expire_response_records(t);
681 :
682 : /*
683 : * check to see if any remote browse sync child processes have completed
684 : */
685 :
686 5884 : sync_check_completion();
687 :
688 : /*
689 : * regularly sync with any other DMBs we know about
690 : */
691 :
692 5884 : if (lp_enhanced_browsing())
693 5884 : sync_all_dmbs(t);
694 :
695 : /* check for new network interfaces */
696 :
697 5884 : reload_interfaces(t);
698 :
699 : /* free up temp memory */
700 5884 : TALLOC_FREE(frame);
701 : }
702 : }
703 :
704 : /**************************************************************************** **
705 : Open the socket communication.
706 : **************************************************************************** */
707 :
708 23 : static bool open_sockets(bool isdaemon, int port)
709 : {
710 : struct sockaddr_storage ss;
711 23 : const char *sock_addr = lp_nbt_client_socket_address();
712 :
713 : /*
714 : * The sockets opened here will be used to receive broadcast
715 : * packets *only*. Interface specific sockets are opened in
716 : * make_subnet() in namedbsubnet.c. Thus we bind to the
717 : * address "0.0.0.0". The parameter 'socket address' is
718 : * now deprecated.
719 : */
720 :
721 23 : if (!interpret_string_addr(&ss, sock_addr,
722 : AI_NUMERICHOST|AI_PASSIVE)) {
723 0 : DEBUG(0,("open_sockets: unable to get socket address "
724 : "from string %s", sock_addr));
725 0 : return false;
726 : }
727 23 : if (ss.ss_family != AF_INET) {
728 0 : DEBUG(0,("open_sockets: unable to use IPv6 socket"
729 : "%s in nmbd\n",
730 : sock_addr));
731 0 : return false;
732 : }
733 :
734 23 : if (isdaemon) {
735 23 : ClientNMB = open_socket_in(SOCK_DGRAM, &ss, port, true);
736 : } else {
737 0 : ClientNMB = 0;
738 : }
739 :
740 23 : if (ClientNMB < 0) {
741 0 : return false;
742 : }
743 :
744 23 : ClientDGRAM = open_socket_in(SOCK_DGRAM, &ss, DGRAM_PORT, true);
745 :
746 23 : if (ClientDGRAM < 0) {
747 0 : if (ClientNMB != 0) {
748 0 : close(ClientNMB);
749 : }
750 0 : return false;
751 : }
752 :
753 : /* we are never interested in SIGPIPE */
754 23 : BlockSignals(True,SIGPIPE);
755 :
756 23 : set_socket_options( ClientNMB, "SO_BROADCAST" );
757 23 : set_socket_options( ClientDGRAM, "SO_BROADCAST" );
758 :
759 : /* Ensure we're non-blocking. */
760 23 : set_blocking( ClientNMB, False);
761 23 : set_blocking( ClientDGRAM, False);
762 :
763 23 : DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
764 23 : return( True );
765 : }
766 :
767 : /**************************************************************************** **
768 : main program
769 : **************************************************************************** */
770 :
771 23 : int main(int argc, const char *argv[])
772 : {
773 23 : struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL;
774 23 : bool log_stdout = false;
775 : poptContext pc;
776 23 : char *p_lmhosts = NULL;
777 : int opt;
778 : struct messaging_context *msg;
779 92 : struct poptOption long_options[] = {
780 : POPT_AUTOHELP
781 : {
782 : .longName = "hosts",
783 : .shortName = 'H',
784 : .argInfo = POPT_ARG_STRING,
785 : .arg = &p_lmhosts,
786 : .val = 0,
787 : .descrip = "Load a netbios hosts file",
788 : },
789 : {
790 : .longName = "port",
791 : .shortName = 'p',
792 : .argInfo = POPT_ARG_INT,
793 : .arg = &global_nmb_port,
794 : .val = 0,
795 : .descrip = "Listen on the specified port",
796 : },
797 23 : POPT_COMMON_SAMBA
798 23 : POPT_COMMON_DAEMON
799 23 : POPT_COMMON_VERSION
800 : POPT_TABLEEND
801 : };
802 15 : const struct loadparm_substitution *lp_sub =
803 8 : loadparm_s3_global_substitution();
804 : TALLOC_CTX *frame;
805 : NTSTATUS status;
806 : bool ok;
807 :
808 : /*
809 : * Do this before any other talloc operation
810 : */
811 23 : talloc_enable_null_tracking();
812 23 : frame = talloc_stackframe();
813 :
814 : /*
815 : * We want total control over the permissions on created files,
816 : * so set our umask to 0.
817 : */
818 23 : umask(0);
819 :
820 23 : smb_init_locale();
821 :
822 23 : ok = samba_cmdline_init(frame,
823 : SAMBA_CMDLINE_CONFIG_SERVER,
824 : true /* require_smbconf */);
825 23 : if (!ok) {
826 0 : DBG_ERR("Failed to init cmdline parser!\n");
827 0 : TALLOC_FREE(frame);
828 0 : exit(ENOMEM);
829 : }
830 :
831 23 : cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg();
832 :
833 23 : global_nmb_port = NMB_PORT;
834 :
835 23 : pc = samba_popt_get_context(getprogname(),
836 : argc,
837 : argv,
838 : long_options,
839 : 0);
840 23 : if (pc == NULL) {
841 0 : DBG_ERR("Failed to setup popt context!\n");
842 0 : TALLOC_FREE(frame);
843 0 : exit(1);
844 : }
845 :
846 23 : while ((opt = poptGetNextOpt(pc)) != -1) {
847 0 : d_fprintf(stderr, "\nInvalid options\n\n");
848 0 : poptPrintUsage(pc, stderr, 0);
849 0 : exit(1);
850 : };
851 23 : poptFreeContext(pc);
852 :
853 23 : global_in_nmbd = true;
854 :
855 23 : StartupTime = time(NULL);
856 :
857 23 : sys_srandom(time(NULL) ^ getpid());
858 :
859 23 : if (is_default_dyn_LOGFILEBASE()) {
860 0 : char *lfile = NULL;
861 0 : if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
862 0 : exit(1);
863 : }
864 0 : lp_set_logfile(lfile);
865 0 : SAFE_FREE(lfile);
866 : }
867 :
868 23 : dump_core_setup("nmbd", lp_logfile(talloc_tos(), lp_sub));
869 :
870 : /* POSIX demands that signals are inherited. If the invoking process has
871 : * these signals masked, we will have problems, as we won't receive them. */
872 23 : BlockSignals(False, SIGHUP);
873 23 : BlockSignals(False, SIGUSR1);
874 23 : BlockSignals(False, SIGTERM);
875 :
876 : #if defined(SIGFPE)
877 : /* we are never interested in SIGFPE */
878 23 : BlockSignals(True,SIGFPE);
879 : #endif
880 :
881 : /* We no longer use USR2... */
882 : #if defined(SIGUSR2)
883 23 : BlockSignals(True, SIGUSR2);
884 : #endif
885 :
886 : /* Ignore children - no zombies. */
887 23 : CatchChild();
888 :
889 23 : log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
890 23 : if ( cmdline_daemon_cfg->interactive ) {
891 0 : log_stdout = True;
892 : }
893 :
894 23 : if ( log_stdout && cmdline_daemon_cfg->fork ) {
895 0 : DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
896 0 : exit(1);
897 : }
898 :
899 23 : reopen_logs();
900 :
901 23 : DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
902 23 : DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));
903 :
904 23 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
905 0 : && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
906 : /* TODO: when we have a merged set of defaults for
907 : * loadparm, we could possibly check if the internal
908 : * nbt server is in the list, and allow a startup if disabled */
909 0 : DEBUG(0, ("server role = 'active directory domain controller' not compatible with running nmbd standalone. \n"));
910 0 : DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal nbt server\n"));
911 0 : exit(1);
912 : }
913 :
914 23 : if (!cluster_probe_ok()) {
915 0 : exit(1);
916 : }
917 :
918 23 : msg = messaging_init(NULL, global_event_context());
919 23 : if (msg == NULL) {
920 0 : DBG_ERR("Failed to init messaging context!\n");
921 0 : return 1;
922 : }
923 :
924 23 : if ( !reload_nmbd_services(False) )
925 0 : return(-1);
926 :
927 23 : if (!nmbd_init_my_netbios_names()) {
928 0 : return -1;
929 : }
930 :
931 23 : reload_nmbd_services( True );
932 :
933 23 : if (strequal(lp_workgroup(),"*")) {
934 0 : DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
935 0 : exit(1);
936 : }
937 :
938 23 : set_samba_nb_type();
939 :
940 23 : if (!cmdline_daemon_cfg->daemon && !is_a_socket(0)) {
941 23 : DEBUG(3, ("standard input is not a socket, assuming -D option\n"));
942 23 : cmdline_daemon_cfg->daemon = true;
943 : }
944 :
945 23 : if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) {
946 23 : DEBUG(3, ("Becoming a daemon.\n"));
947 38 : become_daemon(cmdline_daemon_cfg->fork,
948 23 : cmdline_daemon_cfg->no_process_group,
949 : log_stdout);
950 0 : } else if (!cmdline_daemon_cfg->interactive) {
951 0 : daemon_status("nmbd", "Starting process...");
952 : }
953 :
954 : #ifdef HAVE_SETPGID
955 : /*
956 : * If we're interactive we want to set our own process group for
957 : * signal management.
958 : */
959 23 : if (cmdline_daemon_cfg->interactive &&
960 0 : !cmdline_daemon_cfg->no_process_group)
961 : {
962 0 : setpgid( (pid_t)0, (pid_t)0 );
963 : }
964 : #endif
965 :
966 : #ifndef SYNC_DNS
967 : /* Setup the async dns. We do it here so it doesn't have all the other
968 : stuff initialised and thus chewing memory and sockets */
969 23 : if(lp_we_are_a_wins_server() && lp_wins_dns_proxy()) {
970 0 : start_async_dns(msg);
971 : }
972 : #endif
973 :
974 23 : ok = directory_create_or_exist(lp_lock_directory(), 0755);
975 23 : if (!ok) {
976 0 : exit_daemon("Failed to create directory for lock files, check 'lock directory'", errno);
977 : }
978 :
979 23 : ok = directory_create_or_exist(lp_pid_directory(), 0755);
980 23 : if (!ok) {
981 0 : exit_daemon("Failed to create directory for pid files, check 'pid directory'", errno);
982 : }
983 :
984 23 : pidfile_create(lp_pid_directory(), "nmbd");
985 :
986 23 : status = reinit_after_fork(msg, nmbd_event_context(), false, NULL);
987 :
988 23 : if (!NT_STATUS_IS_OK(status)) {
989 0 : exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status));
990 : }
991 :
992 : /*
993 : * Do not initialize the parent-child-pipe before becoming
994 : * a daemon: this is used to detect a died parent in the child
995 : * process.
996 : */
997 23 : status = init_before_fork();
998 23 : if (!NT_STATUS_IS_OK(status)) {
999 0 : exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1000 : }
1001 :
1002 23 : if (!nmbd_setup_sig_term_handler(msg))
1003 0 : exit_daemon("NMBD failed to setup signal handler", EINVAL);
1004 23 : if (!nmbd_setup_stdin_handler(msg, !cmdline_daemon_cfg->fork))
1005 0 : exit_daemon("NMBD failed to setup stdin handler", EINVAL);
1006 23 : if (!nmbd_setup_sig_hup_handler(msg))
1007 0 : exit_daemon("NMBD failed to setup SIGHUP handler", EINVAL);
1008 :
1009 23 : if (!messaging_parent_dgm_cleanup_init(msg)) {
1010 0 : exit(1);
1011 : }
1012 :
1013 23 : messaging_register(msg, NULL, MSG_FORCE_ELECTION,
1014 : nmbd_message_election);
1015 : #if 0
1016 : /* Until winsrepl is done. */
1017 : messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY,
1018 : nmbd_wins_new_entry);
1019 : #endif
1020 23 : messaging_register(msg, NULL, MSG_SHUTDOWN,
1021 : nmbd_terminate);
1022 23 : messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED,
1023 : msg_reload_nmbd_services);
1024 23 : messaging_register(msg, NULL, MSG_SEND_PACKET,
1025 : msg_nmbd_send_packet);
1026 :
1027 23 : TimeInit();
1028 :
1029 23 : DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
1030 :
1031 23 : if ( !open_sockets( cmdline_daemon_cfg->daemon, global_nmb_port ) ) {
1032 0 : kill_async_dns_child();
1033 0 : return 1;
1034 : }
1035 :
1036 : /* Determine all the IP addresses we have. */
1037 23 : load_interfaces();
1038 :
1039 : /* Create an nmbd subnet record for each of the above. */
1040 23 : if( False == create_subnets() ) {
1041 0 : kill_async_dns_child();
1042 0 : exit_daemon("NMBD failed when creating subnet lists", EACCES);
1043 : }
1044 :
1045 : /* Load in any static local names. */
1046 23 : if (p_lmhosts) {
1047 0 : set_dyn_LMHOSTSFILE(p_lmhosts);
1048 : }
1049 23 : load_lmhosts_file(get_dyn_LMHOSTSFILE());
1050 23 : DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));
1051 :
1052 : /* If we are acting as a WINS server, initialise data structures. */
1053 23 : if( !initialise_wins() ) {
1054 0 : kill_async_dns_child();
1055 0 : exit_daemon( "NMBD failed when initialising WINS server.", EACCES);
1056 : }
1057 :
1058 : /*
1059 : * Register nmbd primary workgroup and nmbd names on all
1060 : * the broadcast subnets, and on the WINS server (if specified).
1061 : * Also initiate the startup of our primary workgroup (start
1062 : * elections if we are setup as being able to be a local
1063 : * master browser.
1064 : */
1065 :
1066 23 : if( False == register_my_workgroup_and_names() ) {
1067 0 : kill_async_dns_child();
1068 0 : exit_daemon( "NMBD failed when creating my workgroup.", EACCES);
1069 : }
1070 :
1071 23 : if (!initialize_nmbd_proxy_logon()) {
1072 0 : kill_async_dns_child();
1073 0 : exit_daemon( "NMBD failed to setup nmbd_proxy_logon.", EACCES);
1074 : }
1075 :
1076 23 : if (!nmbd_init_packet_server()) {
1077 0 : kill_async_dns_child();
1078 0 : exit_daemon( "NMBD failed to setup packet server.", EACCES);
1079 : }
1080 :
1081 23 : if (!cmdline_daemon_cfg->interactive) {
1082 23 : daemon_ready("nmbd");
1083 : }
1084 :
1085 23 : TALLOC_FREE(frame);
1086 23 : process(msg);
1087 :
1088 0 : kill_async_dns_child();
1089 0 : return(0);
1090 : }
|