root/source3/nmbd/nmbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nmbd_event_context
  2. nmbd_messaging_context
  3. terminate
  4. nmbd_sig_term_handler
  5. nmbd_setup_sig_term_handler
  6. nmbd_sig_hup_handler
  7. nmbd_setup_sig_hup_handler
  8. nmbd_terminate
  9. fault_continue
  10. expire_names_and_servers
  11. reload_interfaces
  12. reload_nmbd_services
  13. msg_reload_nmbd_services
  14. msg_nmbd_send_packet
  15. process
  16. open_sockets
  17. main

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

/* [<][>][^][v][top][bottom][index][help] */