~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/nmbd/nmbd.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
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)
 
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)
 
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,
 
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)
 
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,
 
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)
 
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,
 
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)
 
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)
 
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)
 
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)
 
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,
 
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,
 
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)
 
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)
 
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[])
 
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
}