Esempio n. 1
0
/*
  return a count of the number of IPs for a particular tag, including
  dead ones
*/
unsigned wins_srv_count_tag(const char *tag)
{
	const char **list;
	int i, count=0;

	/* if we are a wins server then we always just talk to ourselves */
	if (lp_we_are_a_wins_server()) {
		return 1;
	}

	list = lp_wins_server_list();
	if (!list || !list[0]) {
		return 0;
	}

	/* find the first live one for this tag */
	for (i=0; list[i]; i++) {
		struct tagged_ip t_ip;
		parse_ip(&t_ip, list[i]);
		if (strcmp(tag, t_ip.tag) == 0) {
			count++;
		}
	}

	return count;
}
Esempio n. 2
0
/*
  return the IP of the currently active wins server for the given tag,
  or the zero IP otherwise
*/
struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
{
	const char **list;
	int i;
	struct tagged_ip t_ip;

	/* if we are a wins server then we always just talk to ourselves */
	if (lp_we_are_a_wins_server()) {
		struct in_addr loopback_ip;
		loopback_ip.s_addr = htonl(INADDR_LOOPBACK);
		return loopback_ip;
	}

	list = lp_wins_server_list();
	if (!list || !list[0]) {
		struct in_addr ip;
		zero_ip_v4(&ip);
		return ip;
	}

	/* find the first live one for this tag */
	for (i=0; list[i]; i++) {
		parse_ip(&t_ip, list[i]);
		if (strcmp(tag, t_ip.tag) != 0) {
			/* not for the right tag. Move along */
			continue;
		}
		if (!wins_srv_is_dead(t_ip.ip, src_ip)) {
			fstring src_name;
			fstrcpy(src_name, inet_ntoa(src_ip));
			DEBUG(6,("Current wins server for tag '%s' with source %s is %s\n", 
				 tag, 
				 src_name,
				 inet_ntoa(t_ip.ip)));
			return t_ip.ip;
		}
	}

	/* they're all dead - try the first one until they revive */
	for (i=0; list[i]; i++) {
		parse_ip(&t_ip, list[i]);
		if (strcmp(tag, t_ip.tag) != 0) {
			continue;
		}
		return t_ip.ip;
	}

	/* this can't happen?? */
	zero_ip_v4(&t_ip.ip);
	return t_ip.ip;
}
static int do_global_checks(void)
{
	int ret = 0;
	SMB_STRUCT_STAT st;

	if (lp_security() >= SEC_DOMAIN && !lp_encrypted_passwords()) {
		fprintf(stderr, "ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must always be set to 'true'.\n");
		ret = 1;
	}

	if (lp_we_are_a_wins_server() && lp_wins_server_list()) {
		fprintf(stderr, "ERROR: both 'wins support = true' and 'wins server = <server list>' \
cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
		ret = 1;
	}
Esempio n. 4
0
/*
  return the total number of wins servers, dead or not
*/
unsigned wins_srv_count(void)
{
	const char **list;
	int count = 0;

	if (lp_we_are_a_wins_server()) {
		/* simple - just talk to ourselves */
		return 1;
	}

	list = lp_wins_server_list();
	for (count=0; list && list[count]; count++)
		/* nop */ ;

	return count;
}
Esempio n. 5
0
bool create_subnets(void)
{
	/* We only count IPv4 interfaces whilst we're waiting. */
	int num_interfaces;
	int i;
	struct in_addr unicast_ip, ipzero;

  try_interfaces_again:

	/* Only count IPv4, non-loopback interfaces. */
	if (iface_count_v4_nl() == 0) {
		DEBUG(0,("create_subnets: No local IPv4 non-loopback interfaces !\n"));
		DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));
	}

	/* We only count IPv4, non-loopback interfaces here. */
	while (iface_count_v4_nl() == 0) {
		void (*saved_handler)(int);

		/*
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		/*
		 * We got an interface, restore our normal term handler.
		 */

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
	}

	/*
	 * Here we count v4 and v6 - we know there's at least one
	 * IPv4 interface and we filter on it below.
	 */
	num_interfaces = iface_count();

	/*
	 * Create subnets from all the local interfaces and thread them onto
	 * the linked list.
	 */

	for (i = 0 ; i < num_interfaces; i++) {
		const struct interface *iface = get_interface(i);

		if (!iface) {
			DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
			continue;
		}

		/* Ensure we're only dealing with IPv4 here. */
		if (iface->ip.ss_family != AF_INET) {
			DEBUG(2,("create_subnets: "
				"ignoring non IPv4 interface.\n"));
			continue;
		}

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (is_loopback_addr((struct sockaddr *)&iface->ip)) {
			DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
			continue;
		}

		if (!make_normal_subnet(iface))
			return False;
	}

        /* We must have at least one subnet. */
	if (subnetlist == NULL) {
		void (*saved_handler)(int);

		DEBUG(0,("create_subnets: Unable to create any subnet from "
				"given interfaces. Is your interface line in "
				"smb.conf correct ?\n"));

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		sleep(5);
		load_interfaces();

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
		goto try_interfaces_again;
	}

	if (lp_we_are_a_wins_server()) {
		/* Pick the first interface IPv4 address as the WINS server
		 * ip. */
		const struct in_addr *nip = first_ipv4_iface();

		if (!nip) {
			return False;
		}

		unicast_ip = *nip;
	} else {
		/* note that we do not set the wins server IP here. We just
			set it at zero and let the wins registration code cope
			with getting the IPs right for each packet */
		zero_ip_v4(&unicast_ip);
	}

	/*
	 * Create the unicast and remote broadcast subnets.
	 * Don't put these onto the linked list.
	 * The ip address of the unicast subnet is set to be
	 * the WINS server address, if it exists, or ipzero if not.
	 */

	unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET, 
				unicast_ip, unicast_ip, unicast_ip);

	zero_ip_v4(&ipzero);

	remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
				REMOTE_BROADCAST_SUBNET,
				ipzero, ipzero, ipzero);

	if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
		return False;

	/* 
	 * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
	 * the linked list.
	 */

	if (lp_we_are_a_wins_server()) {
		if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
						WINS_SERVER_SUBNET, 
						ipzero, ipzero, ipzero )) == NULL )
			return False;
	}

	return True;
}
Esempio n. 6
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);
}
Esempio n. 7
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);
}
static int do_global_checks(void)
{
	int ret = 0;
	SMB_STRUCT_STAT st;
	const char *socket_options;

	if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) {
		fprintf(stderr, "ERROR: in 'security=domain' mode the "
				"'encrypt passwords' parameter must always be "
				"set to 'true'.\n\n");
		ret = 1;
	}

	if (lp_we_are_a_wins_server() && lp_wins_server_list()) {
		fprintf(stderr, "ERROR: both 'wins support = true' and "
				"'wins server = <server list>' cannot be set in "
				"the smb.conf file. nmbd will abort with this "
				"setting.\n\n");
		ret = 1;
	}

	if (strequal(lp_workgroup(), lp_netbios_name())) {
		fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' "
				"must differ.\n\n");
	}

	if (!directory_exist_stat(lp_lock_directory(), &st)) {
		fprintf(stderr, "ERROR: lock directory %s does not exist\n\n",
		       lp_lock_directory());
		ret = 1;
	} else if ((st.st_ex_mode & 0777) != 0755) {
		fprintf(stderr, "WARNING: lock directory %s should have "
				"permissions 0755 for browsing to work\n\n",
		       lp_lock_directory());
	}

	if (!directory_exist_stat(lp_state_directory(), &st)) {
		fprintf(stderr, "ERROR: state directory %s does not exist\n\n",
		       lp_state_directory());
		ret = 1;
	} else if ((st.st_ex_mode & 0777) != 0755) {
		fprintf(stderr, "WARNING: state directory %s should have "
				"permissions 0755 for browsing to work\n\n",
		       lp_state_directory());
	}

	if (!directory_exist_stat(lp_cache_directory(), &st)) {
		fprintf(stderr, "ERROR: cache directory %s does not exist\n\n",
		       lp_cache_directory());
		ret = 1;
	} else if ((st.st_ex_mode & 0777) != 0755) {
		fprintf(stderr, "WARNING: cache directory %s should have "
				"permissions 0755 for browsing to work\n\n",
		       lp_cache_directory());
	}

	if (!directory_exist_stat(lp_pid_directory(), &st)) {
		fprintf(stderr, "ERROR: pid directory %s does not exist\n\n",
		       lp_pid_directory());
		ret = 1;
	}

	if (lp_passdb_expand_explicit()) {
		fprintf(stderr, "WARNING: passdb expand explicit = yes is "
				"deprecated\n\n");
	}

	/*
	 * Socket options.
	 */
	socket_options = lp_socket_options();
	if (socket_options != NULL &&
	    (strstr(socket_options, "SO_SNDBUF") ||
	     strstr(socket_options, "SO_RCVBUF") ||
	     strstr(socket_options, "SO_SNDLOWAT") ||
	     strstr(socket_options, "SO_RCVLOWAT")))
	{
		fprintf(stderr,
			"WARNING: socket options = %s\n"
			"This warning is printed because you set one of the\n"
			"following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n"
			"SO_RCVLOWAT\n"
			"Modern server operating systems are tuned for\n"
			"high network performance in the majority of situations;\n"
			"when you set 'socket options' you are overriding those\n"
			"settings.\n"
			"Linux in particular has an auto-tuning mechanism for\n"
			"buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n"
			"disabled if you specify a socket buffer size. This can\n"
			"potentially cripple your TCP/IP stack.\n\n"
			"Getting the 'socket options' correct can make a big\n"
			"difference to your performance, but getting them wrong\n"
			"can degrade it by just as much. As with any other low\n"
			"level setting, if you must make changes to it, make\n "
			"small changes and test the effect before making any\n"
			"large changes.\n\n",
			socket_options);
	}

	/*
	 * Password server sanity checks.
	 */

	if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) {
		const char *sec_setting;
		if(lp_security() == SEC_DOMAIN)
			sec_setting = "domain";
		else if(lp_security() == SEC_ADS)
			sec_setting = "ads";
		else
			sec_setting = "";

		fprintf(stderr, "ERROR: The setting 'security=%s' requires the "
				"'password server' parameter be set to the "
				"default value * or a valid password server.\n\n",
				sec_setting );
		ret = 1;
	}

	if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) {
		const char *sec_setting;
		if(lp_security() == SEC_DOMAIN)
			sec_setting = "domain";
		else if(lp_security() == SEC_ADS)
			sec_setting = "ads";
		else
			sec_setting = "";

		fprintf(stderr, "WARNING: The setting 'security=%s' should NOT "
				"be combined with the 'password server' "
				"parameter.\n"
				"(by default Samba will discover the correct DC "
				"to contact automatically).\n\n",
				sec_setting );
	}

	/*
	 * Password chat sanity checks.
	 */

	if(lp_security() == SEC_USER && lp_unix_password_sync()) {

		/*
		 * Check that we have a valid lp_passwd_program() if not using pam.
		 */

#ifdef WITH_PAM
		if (!lp_pam_password_change()) {
#endif

			if((lp_passwd_program(talloc_tos()) == NULL) ||
			   (strlen(lp_passwd_program(talloc_tos())) == 0))
			{
				fprintf(stderr,
					"ERROR: the 'unix password sync' "
					"parameter is set and there is no valid "
					"'passwd program' parameter.\n\n");
				ret = 1;
			} else {
				const char *passwd_prog;
				char *truncated_prog = NULL;
				const char *p;

				passwd_prog = lp_passwd_program(talloc_tos());
				p = passwd_prog;
				next_token_talloc(talloc_tos(),
						&p,
						&truncated_prog, NULL);
				if (truncated_prog && access(truncated_prog, F_OK) == -1) {
					fprintf(stderr,
						"ERROR: the 'unix password sync' "
						"parameter is set and the "
						"'passwd program' (%s) cannot be "
						"executed (error was %s).\n\n",
						truncated_prog,
						strerror(errno));
					ret = 1;
				}
			}

#ifdef WITH_PAM
		}
#endif

		if(lp_passwd_chat(talloc_tos()) == NULL) {
			fprintf(stderr,
				"ERROR: the 'unix password sync' parameter is "
				"set and there is no valid 'passwd chat' "
				"parameter.\n\n");
			ret = 1;
		}

		if ((lp_passwd_program(talloc_tos()) != NULL) &&
		    (strlen(lp_passwd_program(talloc_tos())) > 0))
		{
			/* check if there's a %u parameter present */
			if(strstr_m(lp_passwd_program(talloc_tos()), "%u") == NULL) {
				fprintf(stderr,
					"ERROR: the 'passwd program' (%s) "
					"requires a '%%u' parameter.\n\n",
					lp_passwd_program(talloc_tos()));
				ret = 1;
			}
		}

		/*
		 * Check that we have a valid script and that it hasn't
		 * been written to expect the old password.
		 */

		if(lp_encrypt_passwords()) {
			if(strstr_m( lp_passwd_chat(talloc_tos()), "%o")!=NULL) {
				fprintf(stderr,
					"ERROR: the 'passwd chat' script [%s] "
					"expects to use the old plaintext "
					"password via the %%o substitution. With "
					"encrypted passwords this is not "
					"possible.\n\n",
					lp_passwd_chat(talloc_tos()) );
				ret = 1;
			}
		}
	}

	if (strlen(lp_winbind_separator()) != 1) {
		fprintf(stderr, "ERROR: the 'winbind separator' parameter must "
				"be a single character.\n\n");
		ret = 1;
	}

	if (*lp_winbind_separator() == '+') {
		fprintf(stderr, "'winbind separator = +' might cause problems "
				"with group membership.\n\n");
	}

	if (lp_algorithmic_rid_base() < BASE_RID) {
		/* Try to prevent admin foot-shooting, we can't put algorithmic
		   rids below 1000, that's the 'well known RIDs' on NT */
		fprintf(stderr, "'algorithmic rid base' must be equal to or "
				"above %lu\n\n", BASE_RID);
	}

	if (lp_algorithmic_rid_base() & 1) {
		fprintf(stderr, "'algorithmic rid base' must be even.\n\n");
	}

#ifndef HAVE_DLOPEN
	if (lp_preload_modules()) {
		fprintf(stderr, "WARNING: 'preload modules = ' set while loading "
				"plugins not supported.\n\n");
	}
#endif

	if (!lp_passdb_backend()) {
		fprintf(stderr, "ERROR: passdb backend must have a value or be "
				"left out\n\n");
	}
	
	if (lp_os_level() > 255) {
		fprintf(stderr, "WARNING: Maximum value for 'os level' is "
				"255!\n\n");
	}

	if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) {
		fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n");
		ret = 1;
	}

	return ret;
}   
Esempio n. 9
0
BOOL create_subnets(void)
{    
	int num_interfaces = iface_count();
	int i;
	struct in_addr unicast_ip, ipzero;

	if(num_interfaces == 0) {
		void (*saved_handler)(int);

		DEBUG(0,("create_subnets: No local interfaces !\n"));
		DEBUG(0,("create_subnets: Waiting for an interface to appear ...\n"));

		/* 
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */

		saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );

		while (iface_count() == 0) {
			sleep(5);
			load_interfaces();
		}

		/* 
		 * We got an interface, restore our normal term handler.
		 */

		CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
	}

	num_interfaces = iface_count();

	/* 
	 * Create subnets from all the local interfaces and thread them onto
	 * the linked list. 
	 */

	for (i = 0 ; i < num_interfaces; i++) {
		struct interface *iface = get_interface(i);

		if (!iface) {
			DEBUG(2,("create_subnets: can't get interface %d.\n", i ));
			continue;
		}

		/*
		 * We don't want to add a loopback interface, in case
		 * someone has added 127.0.0.1 for smbd, nmbd needs to
		 * ignore it here. JRA.
		 */

		if (ip_equal(iface->ip, loopback_ip)) {
			DEBUG(2,("create_subnets: Ignoring loopback interface.\n" ));
			continue;
		}

		if (!make_normal_subnet(iface))
			return False;
	}

        /* We must have at least one subnet. */
	if (subnetlist == NULL) {
		DEBUG(0,("create_subnets: unable to create any subnet from "
				"given interfaces. nmbd is terminating\n"));
		return False;
	}

	if (lp_we_are_a_wins_server()) {
		/* Pick the first interface ip address as the WINS server ip. */
		struct in_addr *nip = iface_n_ip(0);

		if (!nip) {
			return False;
		}

		unicast_ip = *nip;
	} else {
		/* note that we do not set the wins server IP here. We just
			set it at zero and let the wins registration code cope
			with getting the IPs right for each packet */
		zero_ip(&unicast_ip);
	}

	/*
	 * Create the unicast and remote broadcast subnets.
	 * Don't put these onto the linked list.
	 * The ip address of the unicast subnet is set to be
	 * the WINS server address, if it exists, or ipzero if not.
	 */

	unicast_subnet = make_subnet( "UNICAST_SUBNET", UNICAST_SUBNET, 
				unicast_ip, unicast_ip, unicast_ip);

	zero_ip(&ipzero);

	remote_broadcast_subnet = make_subnet( "REMOTE_BROADCAST_SUBNET",
				REMOTE_BROADCAST_SUBNET,
				ipzero, ipzero, ipzero);

	if((unicast_subnet == NULL) || (remote_broadcast_subnet == NULL))
		return False;

	/* 
	 * If we are WINS server, create the WINS_SERVER_SUBNET - don't put on
	 * the linked list.
	 */

	if (lp_we_are_a_wins_server()) {
		if( (wins_server_subnet = make_subnet( "WINS_SERVER_SUBNET",
						WINS_SERVER_SUBNET, 
						ipzero, ipzero, ipzero )) == NULL )
			return False;
	}

	return True;
}