2 Unix SMB/Netbios implementation.
4 NBT netbios routines and daemon - version 2
5 Copyright (C) Andrew Tridgell 1994-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
30 extern int DEBUGLEVEL
;
32 extern pstring debugf
;
33 pstring servicesf
= CONFIGFILE
;
39 int global_nmb_port
= -1;
41 extern pstring myhostname
;
42 static pstring host_file
;
43 extern pstring myname
;
44 extern fstring myworkgroup
;
45 extern char **my_netbios_names
;
47 /* are we running as a daemon ? */
48 static BOOL is_daemon
= False
;
50 /* what server type are we currently */
52 time_t StartupTime
=0;
54 extern struct in_addr ipzero
;
56 /****************************************************************************
58 ****************************************************************************/
61 BlockSignals(True
,SIGTERM
);
63 DEBUG(0,("Got SIGTERM: going down...\n"));
65 /* write out wins.dat file if samba is a WINS server */
68 /* remove all samba names, with wins server if necessary. */
71 /* announce all server entries as 0 time-to-live, 0 type */
72 /* XXXX don't care if we never receive a response back... yet */
73 announce_my_servers_removed();
75 /* XXXX other things: if we are a master browser, force an election? */
78 /* Keep compiler happy.. */
83 /****************************************************************************
85 ****************************************************************************/
86 static int sig_hup(void)
88 BlockSignals(True
,SIGHUP
);
90 DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
92 reload_services(True
);
96 BlockSignals(False
,SIGHUP
);
97 #ifndef DONT_REINSTALL_SIG
98 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
103 /****************************************************************************
105 ****************************************************************************/
106 static int sig_pipe(void)
108 BlockSignals(True
,SIGPIPE
);
110 DEBUG(0,("Got SIGPIPE\n"));
113 BlockSignals(False
,SIGPIPE
);
118 /*******************************************************************
119 prepare to dump a core file - carefully!
120 ********************************************************************/
121 static BOOL
dump_core(void)
125 pstrcpy(dname
,debugf
);
126 if ((p
=strrchr(dname
,'/'))) *p
=0;
127 strcat(dname
,"/corefiles");
129 sys_chown(dname
,getuid(),getgid());
131 if (chdir(dname
)) return(False
);
138 getrlimit(RLIMIT_CORE
, &rlp
);
139 rlp
.rlim_cur
= MAX(4*1024*1024,rlp
.rlim_cur
);
140 setrlimit(RLIMIT_CORE
, &rlp
);
141 getrlimit(RLIMIT_CORE
, &rlp
);
142 DEBUG(3,("Core limits now %d %d\n",rlp
.rlim_cur
,rlp
.rlim_max
));
148 DEBUG(0,("Dumping core in %s\n",dname
));
154 /****************************************************************************
155 possibly continue after a fault
156 ****************************************************************************/
157 static void fault_continue(void)
164 /*******************************************************************
165 expire old names from the namelist and server list
166 ******************************************************************/
167 static void expire_names_and_servers(time_t t
)
169 static time_t lastrun
= 0;
171 if (!lastrun
) lastrun
= t
;
172 if (t
< lastrun
+ 5) return;
179 /*****************************************************************************
180 reload the services file
181 **************************************************************************/
182 BOOL
reload_services(BOOL test
)
185 extern fstring remote_machine
;
187 strcpy(remote_machine
,"nmbd");
192 pstrcpy(fname
,lp_configfile());
193 if (file_exist(fname
,NULL
) && !strcsequal(fname
,servicesf
))
195 pstrcpy(servicesf
,fname
);
200 if (test
&& !lp_file_list_changed())
203 ret
= lp_load(servicesf
,True
);
205 /* perhaps the config filename is now set */
207 DEBUG(3,("services not loaded\n"));
208 reload_services(True
);
211 /* Do a sanity check for a misconfigured nmbd */
212 if(lp_wins_support() && *lp_wins_server()) {
213 DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
214 cannot be set in the smb.conf file. nmbd aborting.\n"));
223 /****************************************************************************
224 load a netbios hosts file
225 ****************************************************************************/
226 static void load_hosts_file(char *fname
)
228 FILE *f
= fopen(fname
,"r");
231 DEBUG(2,("Can't open lmhosts file %s\n",fname
));
237 pstring ip
,name
,flags
,extra
;
238 struct subnet_record
*d
;
241 struct in_addr ipaddr
;
242 enum name_source source
= LMHOSTS
;
244 if (!fgets_slash(line
,sizeof(pstring
),f
)) continue;
246 if (*line
== '#') continue;
254 if (next_token(&ptr
,ip
,NULL
)) ++count
;
255 if (next_token(&ptr
,name
,NULL
)) ++count
;
256 if (next_token(&ptr
,flags
,NULL
)) ++count
;
257 if (next_token(&ptr
,extra
,NULL
)) ++count
;
259 if (count
<= 0) continue;
261 if (count
> 0 && count
< 2) {
262 DEBUG(0,("Ill formed hosts line [%s]\n",line
));
267 DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname
));
271 DEBUG(4, ("lmhost entry: %s %s %s\n", ip
, name
, flags
));
273 if (strchr(flags
,'G') || strchr(flags
,'S')) {
274 DEBUG(0,("group flag in %s ignored (obsolete)\n",fname
));
278 if (strchr(flags
,'M')) {
280 pstrcpy(myname
,name
);
283 ipaddr
= *interpret_addr2(ip
);
284 d
= find_subnet_all(ipaddr
);
286 add_netbios_entry(d
,name
,0x00,NB_ACTIVE
,0,source
,ipaddr
,True
);
287 add_netbios_entry(d
,name
,0x20,NB_ACTIVE
,0,source
,ipaddr
,True
);
295 /****************************************************************************
296 The main select loop.
297 ***************************************************************************/
298 static void process(void)
304 time_t t
= time(NULL
);
305 run_election
= check_elections();
306 if(listen_for_packets(run_election
))
316 query_refresh_names(t
);
318 expire_names_and_servers(t
);
319 expire_netbios_response_entries(t
);
322 write_browse_list(t
);
324 check_master_browser(t
);
330 /****************************************************************************
331 open the socket communication
332 ****************************************************************************/
333 static BOOL
open_sockets(BOOL isdaemon
, int port
)
335 /* The sockets opened here will be used to receive broadcast
336 packets *only*. Interface specific sockets are opened in
337 make_subnet() in namedbsubnet.c. Thus we bind to the
338 address "0.0.0.0". The parameter 'socket address' is
343 ClientNMB
= open_socket_in(SOCK_DGRAM
, port
,0,0);
347 ClientDGRAM
= open_socket_in(SOCK_DGRAM
,DGRAM_PORT
,3,0);
352 signal(SIGPIPE
, SIGNAL_CAST sig_pipe
);
354 set_socket_options(ClientNMB
,"SO_BROADCAST");
355 set_socket_options(ClientDGRAM
,"SO_BROADCAST");
357 DEBUG(3,("open_sockets: Broadcast sockets opened.\n"));
362 /****************************************************************************
363 initialise connect, service and file structs
364 ****************************************************************************/
365 static BOOL
init_structs()
367 extern fstring local_machine
;
375 fstrcpy(myname
,myhostname
);
376 p
= strchr(myname
,'.');
381 /* Add any NETBIOS name aliases. Ensure that the first entry
382 is equal to myname. */
383 /* Work out the max number of netbios aliases that we have */
384 ptr
=lp_netbios_aliases();
385 for (namecount
=0; next_token(&ptr
,nbname
,NULL
); namecount
++)
390 /* Allocate space for the netbios aliases */
391 if((my_netbios_names
=(char **)malloc(sizeof(char *)*(namecount
+1))) == NULL
)
393 DEBUG(0,("init_structs: malloc fail.\n"));
397 /* Use the myname string first */
400 my_netbios_names
[namecount
++] = myname
;
402 ptr
=lp_netbios_aliases();
403 while (next_token(&ptr
,nbname
,NULL
)) {
405 /* Look for duplicates */
407 for(n
=0; n
<namecount
; n
++) {
408 if (strcmp(nbname
, my_netbios_names
[n
])==0)
412 my_netbios_names
[namecount
++]=strdup(nbname
);
415 /* Check the strdups succeeded. */
416 for(n
= 0; n
< namecount
; n
++)
417 if(my_netbios_names
[n
]==NULL
)
419 DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
423 /* Terminate name list */
424 my_netbios_names
[namecount
++]=NULL
;
426 fstrcpy(local_machine
,myname
);
427 trim_string(local_machine
," "," ");
428 p
= strchr(local_machine
,' ');
431 strlower(local_machine
);
433 DEBUG(5, ("Netbios name list:-\n"));
434 for (n
=0; my_netbios_names
[n
]; n
++)
435 DEBUG(5, ("my_netbios_names[%d]=\"%s\"\n", n
, my_netbios_names
[n
]));
440 /****************************************************************************
442 ****************************************************************************/
443 static void usage(char *pname
)
445 DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
447 printf("Usage: %s [-n name] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname
);
448 printf("Version %s\n",VERSION
);
449 printf("\t-D become a daemon\n");
450 printf("\t-p port listen on the specified port\n");
451 printf("\t-d debuglevel set the debuglevel\n");
452 printf("\t-l log basename. Basename for log/debug files\n");
453 printf("\t-n netbiosname. the netbios name to advertise for this host\n");
454 printf("\t-H hosts file load a netbios hosts file\n");
459 /****************************************************************************
461 **************************************************************************/
462 int main(int argc
,char *argv
[])
467 char pidFile
[100] = { 0 };
469 global_nmb_port
= NMB_PORT
;
472 StartupTime
= time(NULL
);
476 strcpy(debugf
,NMBLOGFILE
);
478 setup_logging(argv
[0],False
);
480 charset_initialise();
483 strcpy(host_file
,LMHOSTSFILE
);
486 /* this is for people who can't start the program correctly */
487 while (argc
> 1 && (*argv
[1] != '-')) {
492 fault_setup(fault_continue
);
494 signal(SIGHUP
,SIGNAL_CAST sig_hup
);
495 signal(SIGTERM
,SIGNAL_CAST sig_term
);
497 while ((opt
= getopt(argc
, argv
, "as:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:")) != EOF
)
502 strncpy(pidFile
, optarg
, sizeof(pidFile
));
505 pstrcpy(servicesf
,optarg
);
512 DEBUG(0,("Obsolete option '%c' used\n",opt
));
515 pstrcpy(host_file
,optarg
);
518 pstrcpy(myname
,optarg
);
522 sprintf(debugf
,"%s.nmb",optarg
);
525 pstrcpy(scope
,optarg
);
530 extern BOOL append_log
;
531 append_log
= !append_log
;
538 DEBUGLEVEL
= atoi(optarg
);
541 global_nmb_port
= atoi(optarg
);
548 if (!is_a_socket(0)) {
555 DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION
));
556 DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
558 if(!get_myname(myhostname
,NULL
))
560 DEBUG(0,("Unable to get my hostname - exiting.\n"));
568 if (!reload_services(False
))
571 codepage_initialise(lp_client_code_page());
576 reload_services(True
);
578 pstrcpy(myworkgroup
, lp_workgroup());
580 if (strequal(myworkgroup
,"*")) {
581 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
587 if (!is_daemon
&& !is_a_socket(0)) {
588 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
593 DEBUG(2,("%s becoming a daemon\n",timestring()));
602 if ((fd
= open(pidFile
,
606 O_CREAT
| O_WRONLY
| O_TRUNC
, 0644)) < 0)
608 DEBUG(0,("ERROR: can't open %s: %s\n", pidFile
, strerror(errno
)));
611 if (fcntl_lock(fd
,F_SETLK
,0,1,F_WRLCK
)==False
)
613 DEBUG(0,("ERROR: nmbd is already running\n"));
616 sprintf(buf
, "%u\n", (unsigned int) getpid());
617 if (write(fd
, buf
, strlen(buf
)) < 0)
619 DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile
, strerror(errno
)));
622 /* Leave pid file open & locked for the duration... */
626 DEBUG(3,("Opening sockets %d\n", global_nmb_port
));
628 if (!open_sockets(is_daemon
,global_nmb_port
)) return 1;
631 add_my_subnets(myworkgroup
);
635 DEBUG(3,("Checked names\n"));
637 load_netbios_names();
639 DEBUG(3,("Loaded names\n"));
642 load_hosts_file(host_file
);
643 DEBUG(3,("Loaded hosts file\n"));
646 write_browse_list(time(NULL
));
648 DEBUG(3,("Dumped names\n"));
650 /* We can only take sigterm signals in the select. */
651 BlockSignals(True
,SIGTERM
);