Ejemplo n.º 1
0
 int main(int argc, const char *argv[])
{
	static bool is_daemon;
	static bool opt_interactive;
	static bool Fork = true;
	static bool no_process_group;
	static bool log_stdout;
	poptContext pc;
	char *p_lmhosts = NULL;
	int opt;
	enum {
		OPT_DAEMON = 1000,
		OPT_INTERACTIVE,
		OPT_FORK,
		OPT_NO_PROCESS_GROUP,
		OPT_LOG_STDOUT
	};
	struct poptOption long_options[] = {
	POPT_AUTOHELP
	{"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" },
	{"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" },
	{"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" },
	{"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
	{"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
	{"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"},
	{"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" },
	POPT_COMMON_SAMBA
	{ NULL }
	};
	TALLOC_CTX *frame;
	NTSTATUS status;

	/*
	 * Do this before any other talloc operation
	 */
	talloc_enable_null_tracking();
	frame = talloc_stackframe();

	setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);

	load_case_tables();

	global_nmb_port = NMB_PORT;

	pc = poptGetContext("nmbd", argc, argv, long_options, 0);
	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_DAEMON:
			is_daemon = true;
			break;
		case OPT_INTERACTIVE:
			opt_interactive = true;
			break;
		case OPT_FORK:
			Fork = false;
			break;
		case OPT_NO_PROCESS_GROUP:
			no_process_group = true;
			break;
		case OPT_LOG_STDOUT:
			log_stdout = true;
			break;
		default:
			d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
				  poptBadOption(pc, 0), poptStrerror(opt));
			poptPrintUsage(pc, stderr, 0);
			exit(1);
		}
	};
	poptFreeContext(pc);

	global_in_nmbd = true;
	
	StartupTime = time(NULL);
	
	sys_srandom(time(NULL) ^ sys_getpid());
	
	if (!override_logfile) {
		char *lfile = NULL;
		if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) {
			exit(1);
		}
		lp_set_logfile(lfile);
		SAFE_FREE(lfile);
	}
	
	fault_setup();
	dump_core_setup("nmbd", lp_logfile());
	
	/* POSIX demands that signals are inherited. If the invoking process has
	 * these signals masked, we will have problems, as we won't receive them. */
	BlockSignals(False, SIGHUP);
	BlockSignals(False, SIGUSR1);
	BlockSignals(False, SIGTERM);

#if defined(SIGFPE)
	/* we are never interested in SIGFPE */
	BlockSignals(True,SIGFPE);
#endif

	/* We no longer use USR2... */
#if defined(SIGUSR2)
	BlockSignals(True, SIGUSR2);
#endif

	if ( opt_interactive ) {
		Fork = False;
		log_stdout = True;
	}

	if ( log_stdout && Fork ) {
		DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
		exit(1);
	}

	if (log_stdout) {
		setup_logging(argv[0], DEBUG_STDOUT);
	} else {
		setup_logging( argv[0], DEBUG_FILE);
	}

	reopen_logs();

	DEBUG(0,("nmbd version %s started.\n", samba_version_string()));
	DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));

	if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
		DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
		exit(1);
	}

	if (nmbd_messaging_context() == NULL) {
		return 1;
	}

	if ( !reload_nmbd_services(False) )
		return(-1);

	if(!init_names())
		return -1;

	reload_nmbd_services( True );

	if (strequal(lp_workgroup(),"*")) {
		DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
		exit(1);
	}

	set_samba_nb_type();

	if (!is_daemon && !is_a_socket(0)) {
		DEBUG(0,("standard input is not a socket, assuming -D option\n"));
		is_daemon = True;
	}
  
	if (is_daemon && !opt_interactive) {
		DEBUG( 2, ( "Becoming a daemon.\n" ) );
		become_daemon(Fork, no_process_group, log_stdout);
	}

#if HAVE_SETPGID
	/*
	 * If we're interactive we want to set our own process group for 
	 * signal management.
	 */
	if (opt_interactive && !no_process_group)
		setpgid( (pid_t)0, (pid_t)0 );
#endif

	if (nmbd_messaging_context() == NULL) {
		return 1;
	}

#ifndef SYNC_DNS
	/* Setup the async dns. We do it here so it doesn't have all the other
		stuff initialised and thus chewing memory and sockets */
	if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
		start_async_dns();
	}
#endif

	if (!directory_exist(lp_lockdir())) {
		mkdir(lp_lockdir(), 0755);
	}

	pidfile_create("nmbd");

	status = reinit_after_fork(nmbd_messaging_context(),
				   nmbd_event_context(),
				   procid_self(), false);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("reinit_after_fork() failed\n"));
		exit(1);
	}

	if (!nmbd_setup_sig_term_handler())
		exit(1);
	if (!nmbd_setup_sig_hup_handler())
		exit(1);

	/* get broadcast messages */

	if (!serverid_register(procid_self(),
				FLAG_MSG_GENERAL |
				FLAG_MSG_NMBD |
				FLAG_MSG_DBWRAP)) {
		DEBUG(1, ("Could not register myself in serverid.tdb\n"));
		exit(1);
	}

	messaging_register(nmbd_messaging_context(), NULL,
			   MSG_FORCE_ELECTION, nmbd_message_election);
#if 0
	/* Until winsrepl is done. */
	messaging_register(nmbd_messaging_context(), NULL,
			   MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry);
#endif
	messaging_register(nmbd_messaging_context(), NULL,
			   MSG_SHUTDOWN, nmbd_terminate);
	messaging_register(nmbd_messaging_context(), NULL,
			   MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services);
	messaging_register(nmbd_messaging_context(), NULL,
			   MSG_SEND_PACKET, msg_nmbd_send_packet);

	TimeInit();

	DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );

	if ( !open_sockets( is_daemon, global_nmb_port ) ) {
		kill_async_dns_child();
		return 1;
	}

	/* Determine all the IP addresses we have. */
	load_interfaces();

	/* Create an nmbd subnet record for each of the above. */
	if( False == create_subnets() ) {
		DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
		kill_async_dns_child();
		exit(1);
	}

	/* Load in any static local names. */ 
	if (p_lmhosts) {
		set_dyn_LMHOSTSFILE(p_lmhosts);
	}
	load_lmhosts_file(get_dyn_LMHOSTSFILE());
	DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE()));

	/* If we are acting as a WINS server, initialise data structures. */
	if( !initialise_wins() ) {
		DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
		kill_async_dns_child();
		exit(1);
	}

	/* 
	 * Register nmbd primary workgroup and nmbd names on all
	 * the broadcast subnets, and on the WINS server (if specified).
	 * Also initiate the startup of our primary workgroup (start
	 * elections if we are setup as being able to be a local
	 * master browser.
	 */

	if( False == register_my_workgroup_and_names() ) {
		DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
		kill_async_dns_child();
		exit(1);
	}

	if (!initialize_nmbd_proxy_logon()) {
		DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n"));
		kill_async_dns_child();
		exit(1);
	}

	if (!nmbd_init_packet_server()) {
		kill_async_dns_child();
                exit(1);
        }

	TALLOC_FREE(frame);
	process();

	kill_async_dns_child();
	return(0);
}
Ejemplo n.º 2
0
/**************************************************************************** **
 main program
 **************************************************************************** */
 int main(int argc, const char *argv[])
{
	pstring logfile;
	static BOOL opt_interactive;
	poptContext pc;
	static char *p_lmhosts = dyn_LMHOSTSFILE;
	static BOOL no_process_group = False;
	struct poptOption long_options[] = {
	POPT_AUTOHELP
	{"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
	{"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
	{"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
	{"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
	{"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
	{"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
	{"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
	POPT_COMMON_SAMBA
	{ NULL }
	};

	load_case_tables();

	global_nmb_port = NMB_PORT;

	pc = poptGetContext("nmbd", argc, argv, long_options, 0);
	while (poptGetNextOpt(pc) != -1) {};
	poptFreeContext(pc);

	global_in_nmbd = True;
	
	StartupTime = time(NULL);
	
	sys_srandom(time(NULL) ^ sys_getpid());
	
	if (!override_logfile) {
		slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
		lp_set_logfile(logfile);
	}
	
	fault_setup((void (*)(void *))fault_continue );
	dump_core_setup("nmbd");
	
	/* POSIX demands that signals are inherited. If the invoking process has
	 * these signals masked, we will have problems, as we won't receive them. */
	BlockSignals(False, SIGHUP);
	BlockSignals(False, SIGUSR1);
	BlockSignals(False, SIGTERM);
	
	CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
	CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
	
#if defined(SIGFPE)
	/* we are never interested in SIGFPE */
	BlockSignals(True,SIGFPE);
#endif

	/* We no longer use USR2... */
#if defined(SIGUSR2)
	BlockSignals(True, SIGUSR2);
#endif

	if ( opt_interactive ) {
		Fork = False;
		log_stdout = True;
	}

	if ( log_stdout && Fork ) {
		DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
		exit(1);
	}

	setup_logging( argv[0], log_stdout );

	reopen_logs();

	DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
	DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );

	if ( !reload_nmbd_services(False) )
		return(-1);

	if(!init_names())
		return -1;

	reload_nmbd_services( True );

	if (strequal(lp_workgroup(),"*")) {
		DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
		exit(1);
	}

	set_samba_nb_type();

	if (!is_daemon && !is_a_socket(0)) {
		DEBUG(0,("standard input is not a socket, assuming -D option\n"));
		is_daemon = True;
	}
  
	if (is_daemon && !opt_interactive) {
		DEBUG( 2, ( "Becoming a daemon.\n" ) );
		become_daemon(Fork, no_process_group);
	}

#if HAVE_SETPGID
	/*
	 * If we're interactive we want to set our own process group for 
	 * signal management.
	 */
	if (opt_interactive && !no_process_group)
		setpgid( (pid_t)0, (pid_t)0 );
#endif

#ifndef SYNC_DNS
	/* Setup the async dns. We do it here so it doesn't have all the other
		stuff initialised and thus chewing memory and sockets */
	if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
		start_async_dns();
	}
#endif

	if (!directory_exist(lp_lockdir(), NULL)) {
		mkdir(lp_lockdir(), 0755);
	}

	pidfile_create("nmbd");
	message_init();
	message_register(MSG_FORCE_ELECTION, nmbd_message_election, NULL);
#if 0
	/* Until winsrepl is done. */
	message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry, NULL);
#endif
	message_register(MSG_SHUTDOWN, nmbd_terminate, NULL);
	message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services, NULL);
	message_register(MSG_SEND_PACKET, msg_nmbd_send_packet, NULL);

	TimeInit();

	DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );

	if ( !open_sockets( is_daemon, global_nmb_port ) ) {
		kill_async_dns_child();
		return 1;
	}

	/* Determine all the IP addresses we have. */
	load_interfaces();

	/* Create an nmbd subnet record for each of the above. */
	if( False == create_subnets() ) {
		DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
		kill_async_dns_child();
		exit(1);
	}

	/* Load in any static local names. */ 
	load_lmhosts_file(p_lmhosts);
	DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));

	/* If we are acting as a WINS server, initialise data structures. */
	if( !initialise_wins() ) {
		DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
		kill_async_dns_child();
		exit(1);
	}

	/* 
	 * Register nmbd primary workgroup and nmbd names on all
	 * the broadcast subnets, and on the WINS server (if specified).
	 * Also initiate the startup of our primary workgroup (start
	 * elections if we are setup as being able to be a local
	 * master browser.
	 */

	if( False == register_my_workgroup_and_names() ) {
		DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
		kill_async_dns_child();
		exit(1);
	}

	/* We can only take signals in the select. */
	BlockSignals( True, SIGTERM );

	process();

	if (dbf)
		x_fclose(dbf);
	kill_async_dns_child();
	return(0);
}