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 137848 : struct tevent_context *nmbd_event_context(void)
49 : {
50 137848 : return global_event_context();
51 : }
52 :
53 : /**************************************************************************** **
54 : Handle a SIGTERM in band.
55 : **************************************************************************** */
56 :
57 43 : static void terminate(struct messaging_context *msg)
58 : {
59 43 : DBG_WARNING("Got SIGTERM: going down...\n");
60 :
61 : /* Write out wins.dat file if samba is a WINS server */
62 43 : wins_write_database(0,False);
63 :
64 : /* Remove all SELF registered names from WINS */
65 43 : release_wins_names();
66 :
67 : /* Announce all server entries as 0 time-to-live, 0 type. */
68 43 : announce_my_servers_removed();
69 :
70 : /* If there was an async dns child - kill it. */
71 43 : kill_async_dns_child();
72 :
73 43 : pidfile_unlink(lp_pid_directory(), "nmbd");
74 :
75 43 : 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 43 : 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 43 : if (read(0, &c, 1) != 1) {
101 43 : struct messaging_context *msg = talloc_get_type_abort(
102 : private_data, struct messaging_context);
103 :
104 43 : DBG_WARNING("EOF on stdin\n");
105 43 : terminate(msg);
106 : }
107 0 : }
108 :
109 43 : static bool nmbd_setup_sig_term_handler(struct messaging_context *msg)
110 : {
111 : struct tevent_signal *se;
112 :
113 43 : se = tevent_add_signal(nmbd_event_context(),
114 : nmbd_event_context(),
115 : SIGTERM, 0,
116 : nmbd_sig_term_handler,
117 : msg);
118 43 : if (!se) {
119 0 : DBG_ERR("failed to setup SIGTERM handler\n");
120 0 : return false;
121 : }
122 :
123 43 : return true;
124 : }
125 :
126 43 : static bool nmbd_setup_stdin_handler(struct messaging_context *msg, bool foreground)
127 : {
128 43 : 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 43 : if (fstat(0, &st) != 0) {
136 0 : return false;
137 : }
138 43 : if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
139 43 : 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 43 : 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 : DBG_WARNING("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 43 : static bool nmbd_setup_sig_hup_handler(struct messaging_context *msg)
173 : {
174 : struct tevent_signal *se;
175 :
176 43 : se = tevent_add_signal(nmbd_event_context(),
177 : nmbd_event_context(),
178 : SIGHUP, 0,
179 : nmbd_sig_hup_handler,
180 : msg);
181 43 : if (!se) {
182 0 : DBG_ERR("failed to setup SIGHUP handler\n");
183 0 : return false;
184 : }
185 :
186 43 : 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 17145 : static void expire_names_and_servers(time_t t)
207 : {
208 : static time_t lastrun = 0;
209 :
210 17145 : if ( !lastrun )
211 43 : lastrun = t;
212 17145 : if ( t < (lastrun + 5) )
213 13646 : return;
214 3499 : 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 3499 : 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 3499 : 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 17228 : static void reload_interfaces(time_t t)
241 : {
242 : static time_t lastt;
243 : int n;
244 17228 : bool print_waiting_msg = true;
245 : struct subnet_record *subrec;
246 :
247 17228 : if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
248 16773 : return;
249 : }
250 :
251 455 : lastt = t;
252 :
253 455 : if (!interfaces_changed()) {
254 455 : 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 : DBG_WARNING("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 : DBG_NOTICE("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 : DBG_NOTICE("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 : DBG_NOTICE("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 : DBG_NOTICE("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 : DBG_NOTICE("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 : DBG_WARNING("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 212 : static bool reload_nmbd_services(bool test)
391 : {
392 : const struct loadparm_substitution *lp_sub =
393 212 : loadparm_s3_global_substitution();
394 : bool ret;
395 :
396 212 : set_remote_machine_name("nmbd", False);
397 :
398 212 : if ( lp_loaded() ) {
399 212 : char *fname = lp_next_configfile(talloc_tos(), lp_sub);
400 212 : if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) {
401 0 : set_dyn_CONFIGFILE(fname);
402 0 : test = False;
403 : }
404 212 : TALLOC_FREE(fname);
405 : }
406 :
407 212 : if ( test && !lp_file_list_changed() )
408 147 : return(True);
409 :
410 65 : ret = lp_load_global(get_dyn_CONFIGFILE());
411 :
412 : /* perhaps the config filename is now set */
413 65 : if ( !test ) {
414 43 : DBG_NOTICE( "services not loaded\n" );
415 43 : reload_nmbd_services( True );
416 : }
417 :
418 65 : reopen_logs();
419 :
420 65 : return(ret);
421 : }
422 :
423 : /**************************************************************************** **
424 : * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
425 : **************************************************************************** */
426 :
427 83 : 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 83 : write_browse_list( 0, True );
434 83 : dump_all_namelists();
435 83 : reload_nmbd_services( True );
436 83 : reopen_logs();
437 83 : reload_interfaces(0);
438 83 : nmbd_init_my_netbios_names();
439 83 : }
440 :
441 16 : 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 16 : 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 16 : DBG_DEBUG("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src));
454 :
455 16 : if (data->length != sizeof(struct packet_struct)) {
456 0 : DBG_WARNING("Discarding invalid packet length from %u\n",
457 : (unsigned int)procid_to_pid(&src));
458 0 : return;
459 : }
460 :
461 16 : if ((p->packet_type != NMB_PACKET) &&
462 16 : (p->packet_type != DGRAM_PACKET)) {
463 0 : DBG_WARNING("Discarding invalid packet type from %u: %d\n",
464 : (unsigned int)procid_to_pid(&src), p->packet_type);
465 0 : return;
466 : }
467 :
468 16 : in_addr_to_sockaddr_storage(&ss, p->ip);
469 16 : pss = iface_ip((struct sockaddr *)(void *)&ss);
470 :
471 16 : if (pss == NULL) {
472 0 : DBG_WARNING("Could not find ip for packet from %u\n",
473 : (unsigned int)procid_to_pid(&src));
474 0 : return;
475 : }
476 :
477 16 : local_ip = &((const struct sockaddr_in *)pss)->sin_addr;
478 16 : subrec = FIRST_SUBNET;
479 :
480 16 : p->recv_fd = -1;
481 32 : p->send_fd = (p->packet_type == NMB_PACKET) ?
482 16 : subrec->nmb_sock : subrec->dgram_sock;
483 :
484 16 : for (subrec = FIRST_SUBNET; subrec != NULL;
485 0 : subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
486 16 : if (ip_equal_v4(*local_ip, subrec->myip)) {
487 32 : p->send_fd = (p->packet_type == NMB_PACKET) ?
488 16 : subrec->nmb_sock : subrec->dgram_sock;
489 16 : break;
490 : }
491 : }
492 :
493 16 : if (p->packet_type == DGRAM_PACKET) {
494 16 : p->port = 138;
495 16 : p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
496 16 : p->packet.dgram.header.source_port = 138;
497 : }
498 :
499 16 : send_packet(p);
500 : }
501 :
502 : /**************************************************************************** **
503 : The main select loop.
504 : **************************************************************************** */
505 :
506 13769 : static void process(struct messaging_context *msg)
507 : {
508 : bool run_election;
509 :
510 17145 : while( True ) {
511 17188 : time_t t = time(NULL);
512 17188 : 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 17188 : run_election = check_elections();
521 :
522 : /*
523 : * Read incoming UDP packets.
524 : * (nmbd_packets.c)
525 : */
526 :
527 17188 : 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 17145 : 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 17145 : 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 17145 : 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 17145 : 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 synchronising the domain master
573 : * browser server lists with ourselves as a local
574 : * master browser.
575 : * (nmbd_sendannounce.c)
576 : */
577 :
578 17145 : announce_myself_to_domain_master_browser(t);
579 :
580 : /*
581 : * Fulfill any remote announce requests.
582 : * (nmbd_sendannounce.c)
583 : */
584 :
585 17145 : announce_remote(t);
586 :
587 : /*
588 : * Fulfill any remote browse sync announce requests.
589 : * (nmbd_sendannounce.c)
590 : */
591 :
592 17145 : 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 17145 : refresh_my_names(t);
601 :
602 : /*
603 : * Scan the subnet namelists and server lists and
604 : * expire those that have timed out.
605 : * (nmbd.c)
606 : */
607 :
608 17145 : 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 17145 : 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 17145 : 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 17145 : 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 17145 : 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 17145 : 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 17145 : if (lp_enhanced_browsing())
672 17145 : 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 17145 : retransmit_or_expire_response_records(t);
681 :
682 : /*
683 : * check to see if any remote browse sync child processes have completed
684 : */
685 :
686 17145 : sync_check_completion();
687 :
688 : /*
689 : * regularly sync with any other DMBs we know about
690 : */
691 :
692 17145 : if (lp_enhanced_browsing())
693 17145 : sync_all_dmbs(t);
694 :
695 : /* check for new network interfaces */
696 :
697 17145 : reload_interfaces(t);
698 :
699 : /* free up temp memory */
700 17145 : TALLOC_FREE(frame);
701 : }
702 : }
703 :
704 : /**************************************************************************** **
705 : Open the socket communication.
706 : **************************************************************************** */
707 :
708 43 : static bool open_sockets(bool isdaemon, int port)
709 : {
710 : struct sockaddr_storage ss;
711 43 : 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 43 : if (!interpret_string_addr(&ss, sock_addr,
722 : AI_NUMERICHOST|AI_PASSIVE)) {
723 0 : DBG_ERR("open_sockets: unable to get socket address "
724 : "from string %s\n", sock_addr);
725 0 : return false;
726 : }
727 43 : if (ss.ss_family != AF_INET) {
728 0 : DBG_ERR("open_sockets: unable to use IPv6 socket"
729 : "%s in nmbd\n",
730 : sock_addr);
731 0 : return false;
732 : }
733 :
734 43 : if (isdaemon) {
735 43 : ClientNMB = open_socket_in(SOCK_DGRAM, &ss, port, true);
736 : } else {
737 0 : ClientNMB = 0;
738 : }
739 :
740 43 : if (ClientNMB < 0) {
741 0 : return false;
742 : }
743 :
744 43 : ClientDGRAM = open_socket_in(SOCK_DGRAM, &ss, DGRAM_PORT, true);
745 :
746 43 : 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 43 : BlockSignals(True,SIGPIPE);
755 :
756 43 : set_socket_options( ClientNMB, "SO_BROADCAST" );
757 43 : set_socket_options( ClientDGRAM, "SO_BROADCAST" );
758 :
759 : /* Ensure we're non-blocking. */
760 43 : set_blocking( ClientNMB, False);
761 43 : set_blocking( ClientDGRAM, False);
762 :
763 43 : DBG_INFO( "open_sockets: Broadcast sockets opened.\n" );
764 43 : return( True );
765 : }
766 :
767 : /**************************************************************************** **
768 : main program
769 : **************************************************************************** */
770 :
771 43 : int main(int argc, const char *argv[])
772 : {
773 43 : struct samba_cmdline_daemon_cfg *cmdline_daemon_cfg = NULL;
774 43 : bool log_stdout = false;
775 : poptContext pc;
776 43 : char *p_lmhosts = NULL;
777 : int opt;
778 : struct messaging_context *msg;
779 172 : 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 43 : POPT_COMMON_SAMBA
798 43 : POPT_COMMON_DAEMON
799 43 : POPT_COMMON_VERSION
800 : POPT_TABLEEND
801 : };
802 : const struct loadparm_substitution *lp_sub =
803 43 : 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 43 : talloc_enable_null_tracking();
812 43 : 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 43 : umask(0);
819 :
820 43 : smb_init_locale();
821 :
822 43 : ok = samba_cmdline_init(frame,
823 : SAMBA_CMDLINE_CONFIG_SERVER,
824 : true /* require_smbconf */);
825 43 : if (!ok) {
826 0 : DBG_ERR("Failed to init cmdline parser!\n");
827 0 : TALLOC_FREE(frame);
828 0 : exit(ENOMEM);
829 : }
830 :
831 43 : cmdline_daemon_cfg = samba_cmdline_get_daemon_cfg();
832 :
833 43 : global_nmb_port = NMB_PORT;
834 :
835 43 : pc = samba_popt_get_context(getprogname(),
836 : argc,
837 : argv,
838 : long_options,
839 : 0);
840 43 : 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 43 : 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 43 : poptFreeContext(pc);
852 :
853 43 : global_in_nmbd = true;
854 :
855 43 : StartupTime = time(NULL);
856 :
857 43 : sys_srandom(time(NULL) ^ getpid());
858 :
859 43 : 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 43 : 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 43 : BlockSignals(False, SIGHUP);
873 43 : BlockSignals(False, SIGUSR1);
874 43 : BlockSignals(False, SIGTERM);
875 :
876 : #if defined(SIGFPE)
877 : /* we are never interested in SIGFPE */
878 43 : BlockSignals(True,SIGFPE);
879 : #endif
880 :
881 : /* We no longer use USR2... */
882 : #if defined(SIGUSR2)
883 43 : BlockSignals(True, SIGUSR2);
884 : #endif
885 :
886 : /* Ignore children - no zombies. */
887 43 : CatchChild();
888 :
889 43 : log_stdout = (debug_get_log_type() == DEBUG_STDOUT);
890 43 : if ( cmdline_daemon_cfg->interactive ) {
891 0 : log_stdout = True;
892 : }
893 :
894 43 : if ( log_stdout && cmdline_daemon_cfg->fork ) {
895 0 : DBG_ERR("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n");
896 0 : exit(1);
897 : }
898 :
899 43 : reopen_logs();
900 :
901 43 : DBG_STARTUP_NOTICE("nmbd version %s started.\n%s\n",
902 : samba_version_string(),
903 : samba_copyright_string());
904 :
905 43 : if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
906 0 : && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
907 : /* TODO: when we have a merged set of defaults for
908 : * loadparm, we could possibly check if the internal
909 : * nbt server is in the list, and allow a startup if disabled */
910 0 : DBG_ERR("server role = 'active directory domain controller' not compatible with running nmbd standalone.\n"
911 : "You should start 'samba' instead, and it will control starting the internal nbt server\n");
912 0 : exit(1);
913 : }
914 :
915 43 : if (!cluster_probe_ok()) {
916 0 : exit(1);
917 : }
918 :
919 43 : msg = messaging_init(NULL, global_event_context());
920 43 : if (msg == NULL) {
921 0 : DBG_ERR("Failed to init messaging context!\n");
922 0 : return 1;
923 : }
924 :
925 43 : if ( !reload_nmbd_services(False) )
926 0 : return(-1);
927 :
928 43 : if (!nmbd_init_my_netbios_names()) {
929 0 : return -1;
930 : }
931 :
932 43 : reload_nmbd_services( True );
933 :
934 43 : if (strequal(lp_workgroup(),"*")) {
935 0 : DBG_ERR("ERROR: a workgroup name of * is no longer supported\n");
936 0 : exit(1);
937 : }
938 :
939 43 : set_samba_nb_type();
940 :
941 43 : if (!cmdline_daemon_cfg->daemon && !is_a_socket(0)) {
942 43 : DBG_NOTICE("standard input is not a socket, assuming -D option\n");
943 43 : cmdline_daemon_cfg->daemon = true;
944 : }
945 :
946 43 : if (cmdline_daemon_cfg->daemon && !cmdline_daemon_cfg->interactive) {
947 43 : DBG_NOTICE("Becoming a daemon.\n");
948 43 : become_daemon(cmdline_daemon_cfg->fork,
949 43 : cmdline_daemon_cfg->no_process_group,
950 : log_stdout);
951 0 : } else if (!cmdline_daemon_cfg->interactive) {
952 0 : daemon_status("nmbd", "Starting process...");
953 : }
954 :
955 : #ifdef HAVE_SETPGID
956 : /*
957 : * If we're interactive we want to set our own process group for
958 : * signal management.
959 : */
960 43 : if (cmdline_daemon_cfg->interactive &&
961 0 : !cmdline_daemon_cfg->no_process_group)
962 : {
963 0 : setpgid( (pid_t)0, (pid_t)0 );
964 : }
965 : #endif
966 :
967 : #ifndef SYNC_DNS
968 : /* Setup the async dns. We do it here so it doesn't have all the other
969 : stuff initialised and thus chewing memory and sockets */
970 43 : if(lp_we_are_a_wins_server() && lp_wins_dns_proxy()) {
971 0 : start_async_dns(msg);
972 : }
973 : #endif
974 :
975 43 : ok = directory_create_or_exist(lp_lock_directory(), 0755);
976 43 : if (!ok) {
977 0 : exit_daemon("Failed to create directory for lock files, check 'lock directory'", errno);
978 : }
979 :
980 43 : ok = directory_create_or_exist(lp_pid_directory(), 0755);
981 43 : if (!ok) {
982 0 : exit_daemon("Failed to create directory for pid files, check 'pid directory'", errno);
983 : }
984 :
985 43 : pidfile_create(lp_pid_directory(), "nmbd");
986 :
987 43 : status = reinit_after_fork(msg, nmbd_event_context(), false);
988 :
989 43 : if (!NT_STATUS_IS_OK(status)) {
990 0 : exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status));
991 : }
992 :
993 : /*
994 : * Do not initialize the parent-child-pipe before becoming
995 : * a daemon: this is used to detect a died parent in the child
996 : * process.
997 : */
998 43 : status = init_before_fork();
999 43 : if (!NT_STATUS_IS_OK(status)) {
1000 0 : exit_daemon(nt_errstr(status), map_errno_from_nt_status(status));
1001 : }
1002 :
1003 43 : if (!nmbd_setup_sig_term_handler(msg))
1004 0 : exit_daemon("NMBD failed to setup signal handler", EINVAL);
1005 43 : if (!nmbd_setup_stdin_handler(msg, !cmdline_daemon_cfg->fork))
1006 0 : exit_daemon("NMBD failed to setup stdin handler", EINVAL);
1007 43 : if (!nmbd_setup_sig_hup_handler(msg))
1008 0 : exit_daemon("NMBD failed to setup SIGHUP handler", EINVAL);
1009 :
1010 43 : if (!messaging_parent_dgm_cleanup_init(msg)) {
1011 0 : exit(1);
1012 : }
1013 :
1014 43 : messaging_register(msg, NULL, MSG_FORCE_ELECTION,
1015 : nmbd_message_election);
1016 : #if 0
1017 : /* Until winsrepl is done. */
1018 : messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY,
1019 : nmbd_wins_new_entry);
1020 : #endif
1021 43 : messaging_register(msg, NULL, MSG_SHUTDOWN,
1022 : nmbd_terminate);
1023 43 : messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED,
1024 : msg_reload_nmbd_services);
1025 43 : messaging_register(msg, NULL, MSG_SEND_PACKET,
1026 : msg_nmbd_send_packet);
1027 :
1028 43 : TimeInit();
1029 :
1030 43 : DBG_NOTICE("Opening sockets %d\n", global_nmb_port);
1031 :
1032 43 : if ( !open_sockets( cmdline_daemon_cfg->daemon, global_nmb_port ) ) {
1033 0 : kill_async_dns_child();
1034 0 : return 1;
1035 : }
1036 :
1037 : /* Determine all the IP addresses we have. */
1038 43 : load_interfaces();
1039 :
1040 : /* Create an nmbd subnet record for each of the above. */
1041 43 : if( False == create_subnets() ) {
1042 0 : kill_async_dns_child();
1043 0 : exit_daemon("NMBD failed when creating subnet lists", EACCES);
1044 : }
1045 :
1046 : /* Load in any static local names. */
1047 43 : if (p_lmhosts) {
1048 0 : set_dyn_LMHOSTSFILE(p_lmhosts);
1049 : }
1050 43 : load_lmhosts_file(get_dyn_LMHOSTSFILE());
1051 43 : DBG_NOTICE("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE());
1052 :
1053 : /* If we are acting as a WINS server, initialise data structures. */
1054 43 : if( !initialise_wins() ) {
1055 0 : kill_async_dns_child();
1056 0 : exit_daemon( "NMBD failed when initialising WINS server.", EACCES);
1057 : }
1058 :
1059 : /*
1060 : * Register nmbd primary workgroup and nmbd names on all
1061 : * the broadcast subnets, and on the WINS server (if specified).
1062 : * Also initiate the startup of our primary workgroup (start
1063 : * elections if we are setup as being able to be a local
1064 : * master browser.
1065 : */
1066 :
1067 43 : if( False == register_my_workgroup_and_names() ) {
1068 0 : kill_async_dns_child();
1069 0 : exit_daemon( "NMBD failed when creating my workgroup.", EACCES);
1070 : }
1071 :
1072 43 : if (!initialize_nmbd_proxy_logon()) {
1073 0 : kill_async_dns_child();
1074 0 : exit_daemon( "NMBD failed to setup nmbd_proxy_logon.", EACCES);
1075 : }
1076 :
1077 43 : if (!nmbd_init_packet_server()) {
1078 0 : kill_async_dns_child();
1079 0 : exit_daemon( "NMBD failed to setup packet server.", EACCES);
1080 : }
1081 :
1082 43 : if (!cmdline_daemon_cfg->interactive) {
1083 43 : daemon_ready("nmbd");
1084 : }
1085 :
1086 43 : TALLOC_FREE(frame);
1087 43 : process(msg);
1088 :
1089 0 : kill_async_dns_child();
1090 0 : return(0);
1091 : }
|