Example #1
0
static bool open_sockets(void)
{
	struct sockaddr_storage ss;
	const char *sock_addr = lp_socket_address();

	if (!interpret_string_addr(&ss, sock_addr,
				AI_NUMERICHOST|AI_PASSIVE)) {
		DEBUG(0,("open_sockets: unable to get socket address "
					"from string %s", sock_addr));
		return false;
	}
	ServerFD = open_socket_in( SOCK_DGRAM,
				(RootPort ? 137 : 0),
				(RootPort ?   0 : 3),
				&ss, true );

	if (ServerFD == -1) {
		return false;
	}

	set_socket_options( ServerFD, "SO_BROADCAST" );

	DEBUG(3, ("Socket opened.\n"));
	return true;
}
Example #2
0
/*
  startup the web server task
*/
static void websrv_task_init(struct task_server *task)
{
	NTSTATUS status;
	uint16_t port = lp_web_port(task->lp_ctx);
	const struct model_ops *model_ops;
	struct web_server_data *wdata;

	task_server_set_title(task, "task[websrv]");

	/* run the web server as a single process */
	model_ops = process_model_startup(task->event_ctx, "single");
	if (!model_ops) goto failed;

	if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) {
		int num_interfaces;
		int i;
		struct interface *ifaces;

		load_interfaces(NULL, lp_interfaces(task->lp_ctx), &ifaces);

		num_interfaces = iface_count(ifaces);
		for(i = 0; i < num_interfaces; i++) {
			const char *address = iface_n_ip(ifaces, i);
			status = stream_setup_socket(task->event_ctx, 
						     task->lp_ctx, model_ops, 
						     &web_stream_ops, 
						     "ipv4", address, 
						     &port, lp_socket_options(task->lp_ctx), 
						     task);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}

		talloc_free(ifaces);
	} else {
		status = stream_setup_socket(task->event_ctx, task->lp_ctx,
					     model_ops, &web_stream_ops, 
					     "ipv4", lp_socket_address(task->lp_ctx), 
					     &port, lp_socket_options(task->lp_ctx), task);
		if (!NT_STATUS_IS_OK(status)) goto failed;
	}

	/* startup the esp processor - unfortunately we can't do this
	   per connection as that wouldn't allow for session variables */
	wdata = talloc_zero(task, struct web_server_data);
	if (wdata == NULL)goto failed;

	task->private_data = wdata;
	
	wdata->tls_params = tls_initialise(wdata, task->lp_ctx);
	if (wdata->tls_params == NULL) goto failed;

	if (!wsgi_initialize(wdata)) goto failed;

	return;

failed:
	task_server_terminate(task, "websrv_task_init: failed to startup web server task", true);
}
Example #3
0
static BOOL open_sockets(BOOL isdaemon, int port)
{
	/*
	 * The sockets opened here will be used to receive broadcast
	 * packets *only*. Interface specific sockets are opened in
	 * make_subnet() in namedbsubnet.c. Thus we bind to the
	 * address "0.0.0.0". The parameter 'socket address' is
	 * now deprecated.
	 */

	if ( isdaemon )
		ClientNMB = open_socket_in(SOCK_DGRAM, port,
					   0, interpret_addr(lp_socket_address()),
					   True);
	else
		ClientNMB = 0;
  
	ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					   3, interpret_addr(lp_socket_address()),
					   True);

	if ( ClientNMB == -1 )
		return( False );

#ifndef _XBOX
	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);
#endif

	set_socket_options( ClientNMB,   "SO_BROADCAST" );
	set_socket_options( ClientDGRAM, "SO_BROADCAST" );

	/* Ensure we're non-blocking. */
	set_blocking( ClientNMB, False);
	set_blocking( ClientDGRAM, False);

	DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
	return( True );
}
Example #4
0
/****************************************************************************
  open the socket communication
  **************************************************************************/
static BOOL open_sockets(void)
{
  ServerFD = open_socket_in( SOCK_DGRAM,
                             (RootPort ? 137 : 0),
                             (RootPort ?   0 : 3),
                             interpret_addr(lp_socket_address()), True );

  if (ServerFD == -1)
    return(False);

  set_socket_options( ServerFD, "SO_BROADCAST" );

  DEBUG(3, ("Socket opened.\n"));
  return True;
}
Example #5
0
/********************************************************
resolve via "wins" method
*********************************************************/
static BOOL
resolve_wins (const char *name, struct in_addr *return_ip, int name_type)
{
    int sock;
    struct in_addr wins_ip;
    BOOL wins_ismyip;

    /*
     * "wins" means do a unicast lookup to the WINS server.
     * Ignore if there is no WINS server specified or if the
     * WINS server is one of our interfaces (if we're being
     * called from within nmbd - we can't do this call as we
     * would then block).
     */

    DEBUG (3, ("resolve_name: Attempting wins lookup for name %s<0x%x>\n", name, name_type));

    if (!*lp_wins_server ())
    {
        DEBUG (3, ("resolve_name: WINS server resolution selected and no WINS server present.\n"));
        return False;
    }

    wins_ip = *interpret_addr2 (lp_wins_server ());
    wins_ismyip = ismyip (wins_ip);

    if ((wins_ismyip && !global_in_nmbd) || !wins_ismyip)
    {
        sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True);

        if (sock != -1)
        {
            struct in_addr *iplist = NULL;
            int count;
            iplist = name_query (sock, name, name_type, False, True, wins_ip, &count, NULL);
            if (iplist != NULL)
            {
                *return_ip = iplist[0];
                free ((char *) iplist);
                close (sock);
                return True;
            }
            close (sock);
        }
    }

    return False;
}
Example #6
0
/********************************************************
resolve via "bcast" method
*********************************************************/
static BOOL
resolve_bcast (const char *name, struct in_addr *return_ip, int name_type)
{
    int sock, i;

    /*
     * "bcast" means do a broadcast lookup on all the local interfaces.
     */

    DEBUG (3, ("resolve_name: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));

    sock = open_socket_in (SOCK_DGRAM, 0, 3, interpret_addr (lp_socket_address ()), True);

    if (sock != -1)
    {
        struct in_addr *iplist = NULL;
        int count;
        int num_interfaces = iface_count ();
        static char so_broadcast[] = "SO_BROADCAST";
        set_socket_options (sock, so_broadcast);
        /*
         * Lookup the name on all the interfaces, return on
         * the first successful match.
         */
        for (i = 0; i < num_interfaces; i++)
        {
            struct in_addr sendto_ip;
            /* Done this way to fix compiler error on IRIX 5.x */
            sendto_ip = *iface_bcast (*iface_n_ip (i));
            iplist = name_query (sock, name, name_type, True, True, sendto_ip, &count, NULL);
            if (iplist != NULL)
            {
                *return_ip = iplist[0];
                free ((char *) iplist);
                close (sock);
                return True;
            }
        }
        close (sock);
    }

    return False;
}
Example #7
0
static bool epmd_open_sockets(struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx)
{
	uint32_t num_ifs = iface_count();
	uint16_t port;
	uint32_t i;

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/*
		 * We have been given an interfaces line, and been told to only
		 * bind to those interfaces. Create a socket per interface and
		 * bind to only these.
		 */

		/* Now open a listen socket for each of the interfaces. */
		for(i = 0; i < num_ifs; i++) {
			const struct sockaddr_storage *ifss =
					iface_n_sockaddr_storage(i);

			port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
							       msg_ctx,
							       ndr_table_epmapper.syntax_id,
							       ifss,
							       135);
			if (port == 0) {
				return false;
			}
		}
	} else {
		const char *sock_addr = lp_socket_address();
		const char *sock_ptr;
		char *sock_tok;

		if (strequal(sock_addr, "0.0.0.0") ||
		    strequal(sock_addr, "::")) {
#if HAVE_IPV6
			sock_addr = "::";
#else
			sock_addr = "0.0.0.0";
#endif
		}

		for (sock_ptr = sock_addr;
		     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,");
		    ) {
			struct sockaddr_storage ss;

			/* open an incoming socket */
			if (!interpret_string_addr(&ss,
						   sock_tok,
						   AI_NUMERICHOST|AI_PASSIVE)) {
				continue;
			}

			port = setup_dcerpc_ncacn_tcpip_socket(ev_ctx,
							       msg_ctx,
							       ndr_table_epmapper.syntax_id,
							       &ss,
							       135);
			if (port == 0) {
				return false;
			}
		}
	}

	return true;
}
Example #8
0
static bool open_sockets_smbd(struct smbd_parent_context *parent,
			      struct tevent_context *ev_ctx,
			      struct messaging_context *msg_ctx,
			      const char *smb_ports)
{
	int num_interfaces = iface_count();
	int i;
	const char *ports;
	unsigned dns_port = 0;

#ifdef HAVE_ATEXIT
	atexit(killkids);
#endif

	/* Stop zombies */
	smbd_setup_sig_chld_handler(ev_ctx);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = talloc_strdup(talloc_tos(), SMB_PORTS);
		} else {
			ports = talloc_strdup(talloc_tos(), ports);
		}
	} else {
		ports = talloc_strdup(talloc_tos(), smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/

		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			const struct sockaddr_storage *ifss =
					iface_n_sockaddr_storage(i);
			char *tok;
			const char *ptr;

			if (ifss == NULL) {
				DEBUG(0,("open_sockets_smbd: "
					"interface %d has NULL IP address !\n",
					i));
				continue;
			}

			for (ptr=ports;
			     next_token_talloc(talloc_tos(),&ptr, &tok, " \t,");) {
				unsigned port = atoi(tok);
				if (port == 0 || port > 0xffff) {
					continue;
				}

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				if (!smbd_open_one_socket(parent,
							  ev_ctx,
							  msg_ctx,
							  ifss,
							  port)) {
					return false;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		char *tok;
		const char *ptr;
		const char *sock_addr = lp_socket_address();
		char *sock_tok;
		const char *sock_ptr;

		if (strequal(sock_addr, "0.0.0.0") ||
		    strequal(sock_addr, "::")) {
#if HAVE_IPV6
			sock_addr = "::,0.0.0.0";
#else
			sock_addr = "0.0.0.0";
#endif
		}

		for (sock_ptr=sock_addr;
		     next_token_talloc(talloc_tos(), &sock_ptr, &sock_tok, " \t,"); ) {
			for (ptr=ports; next_token_talloc(talloc_tos(), &ptr, &tok, " \t,"); ) {
				struct sockaddr_storage ss;

				unsigned port = atoi(tok);
				if (port == 0 || port > 0xffff) {
					continue;
				}

				/* Keep the first port for mDNS service
				 * registration.
				 */
				if (dns_port == 0) {
					dns_port = port;
				}

				/* open an incoming socket */
				if (!interpret_string_addr(&ss, sock_tok,
						AI_NUMERICHOST|AI_PASSIVE)) {
					continue;
				}

				if (!smbd_open_one_socket(parent,
							  ev_ctx,
							  msg_ctx,
							  &ss,
							  port)) {
					return false;
				}
			}
		}
	}

	if (parent->sockets == NULL) {
		DEBUG(0,("open_sockets_smbd: No "
			"sockets available to bind to.\n"));
		return false;
	}

	/* Setup the main smbd so that we can get messages. Note that
	   do this after starting listening. This is needed as when in
	   clustered mode, ctdb won't allow us to start doing database
	   operations until it has gone thru a full startup, which
	   includes checking to see that smbd is listening. */

	if (!serverid_register(procid_self(),
			       FLAG_MSG_GENERAL|FLAG_MSG_SMBD
			       |FLAG_MSG_PRINT_GENERAL
			       |FLAG_MSG_DBWRAP)) {
		DEBUG(0, ("open_sockets_smbd: Failed to register "
			  "myself in serverid.tdb\n"));
		return false;
	}

        /* Listen to messages */

	messaging_register(msg_ctx, NULL, MSG_SMB_SAM_SYNC, msg_sam_sync);
	messaging_register(msg_ctx, NULL, MSG_SHUTDOWN, msg_exit_server);
	messaging_register(msg_ctx, NULL, MSG_SMB_FILE_RENAME,
			   msg_file_was_renamed);
	messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
			   smb_conf_updated);
	messaging_register(msg_ctx, NULL, MSG_SMB_STAT_CACHE_DELETE,
			   smb_stat_cache_delete);
	messaging_register(msg_ctx, NULL, MSG_DEBUG, smbd_msg_debug);
	messaging_register(msg_ctx, ev_ctx, MSG_PRINTER_PCAP,
			   smb_pcap_updated);
	brl_register_msgs(msg_ctx);

	msg_idmap_register_msg(msg_ctx);

#ifdef CLUSTER_SUPPORT
	if (lp_clustering()) {
		ctdbd_register_reconfigure(messaging_ctdbd_connection());
	}
#endif

#ifdef DEVELOPER
	messaging_register(msg_ctx, NULL, MSG_SMB_INJECT_FAULT,
			   msg_inject_fault);
#endif

	if (lp_multicast_dns_register() && (dns_port != 0)) {
#ifdef WITH_DNSSD_SUPPORT
		smbd_setup_mdns_registration(ev_ctx,
					     parent, dns_port);
#endif
#ifdef WITH_AVAHI_SUPPORT
		void *avahi_conn;

		avahi_conn = avahi_start_register(ev_ctx,
						  ev_ctx,
						  dns_port);
		if (avahi_conn == NULL) {
			DEBUG(10, ("avahi_start_register failed\n"));
		}
#endif
	}

	return true;
}
Example #9
0
static bool open_sockets(bool isdaemon, int port)
{
	struct sockaddr_storage ss;
	const char *sock_addr = lp_socket_address();

	/*
	 * The sockets opened here will be used to receive broadcast
	 * packets *only*. Interface specific sockets are opened in
	 * make_subnet() in namedbsubnet.c. Thus we bind to the
	 * address "0.0.0.0". The parameter 'socket address' is
	 * now deprecated.
	 */

	if (!interpret_string_addr(&ss, sock_addr,
				AI_NUMERICHOST|AI_PASSIVE)) {
		DEBUG(0,("open_sockets: unable to get socket address "
			"from string %s", sock_addr));
		return false;
	}
	if (ss.ss_family != AF_INET) {
		DEBUG(0,("open_sockets: unable to use IPv6 socket"
			"%s in nmbd\n",
			sock_addr));
		return false;
	}

	if (isdaemon) {
		ClientNMB = open_socket_in(SOCK_DGRAM, port,
					   0, &ss,
					   true);
	} else {
		ClientNMB = 0;
	}

	if (ClientNMB == -1) {
		return false;
	}

	ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
					   3, &ss,
					   true);

	if (ClientDGRAM == -1) {
		if (ClientNMB != 0) {
			close(ClientNMB);
		}
		return false;
	}

	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);

	set_socket_options( ClientNMB,   "SO_BROADCAST" );
	set_socket_options( ClientDGRAM, "SO_BROADCAST" );

	/* Ensure we're non-blocking. */
	set_blocking( ClientNMB, False);
	set_blocking( ClientDGRAM, False);

	DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
	return( True );
}
Example #10
0
/*
  open the ldap server sockets
*/
static void ldapsrv_task_init(struct task_server *task)
{	
	char *ldapi_path;
#ifdef WITH_LDAPI_PRIV_SOCKET
	char *priv_dir;
#endif
	struct ldapsrv_service *ldap_service;
	NTSTATUS status;
	const struct model_ops *model_ops;

	switch (lp_server_role(task->lp_ctx)) {
	case ROLE_STANDALONE:
		task_server_terminate(task, "ldap_server: no LDAP server required in standalone configuration", 
				      false);
		return;
	case ROLE_DOMAIN_MEMBER:
		task_server_terminate(task, "ldap_server: no LDAP server required in member server configuration", 
				      false);
		return;
	case ROLE_DOMAIN_CONTROLLER:
		/* Yes, we want an LDAP server */
		break;
	}

	task_server_set_title(task, "task[ldapsrv]");

	/* run the ldap server as a single process */
	model_ops = process_model_startup(task->event_ctx, "single");
	if (!model_ops) goto failed;

	ldap_service = talloc_zero(task, struct ldapsrv_service);
	if (ldap_service == NULL) goto failed;

	ldap_service->task = task;

	ldap_service->tls_params = tls_initialise(ldap_service, task->lp_ctx);
	if (ldap_service->tls_params == NULL) goto failed;

	if (lp_interfaces(task->lp_ctx) && lp_bind_interfaces_only(task->lp_ctx)) {
		struct interface *ifaces;
		int num_interfaces;
		int i;

		load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces);
		num_interfaces = iface_count(ifaces);

		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		for(i = 0; i < num_interfaces; i++) {
			const char *address = iface_n_ip(ifaces, i);
			status = add_socket(task->event_ctx, task->lp_ctx, model_ops, address, ldap_service);
			if (!NT_STATUS_IS_OK(status)) goto failed;
		}
	} else {
		status = add_socket(task->event_ctx, task->lp_ctx, model_ops, 
				    lp_socket_address(task->lp_ctx), ldap_service);
		if (!NT_STATUS_IS_OK(status)) goto failed;
	}

	ldapi_path = private_path(ldap_service, task->lp_ctx, "ldapi");
	if (!ldapi_path) {
		goto failed;
	}

	status = stream_setup_socket(task->event_ctx, task->lp_ctx,
				     model_ops, &ldap_stream_nonpriv_ops,
				     "unix", ldapi_path, NULL, 
				     lp_socket_options(task->lp_ctx), 
				     ldap_service);
	talloc_free(ldapi_path);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
			 ldapi_path, nt_errstr(status)));
	}

#ifdef WITH_LDAPI_PRIV_SOCKET
	priv_dir = private_path(ldap_service, task->lp_ctx, "ldap_priv");
	if (priv_dir == NULL) {
		goto failed;
	}
	/*
	 * Make sure the directory for the privileged ldapi socket exists, and
	 * is of the correct permissions
	 */
	if (!directory_create_or_exist(priv_dir, geteuid(), 0750)) {
		task_server_terminate(task, "Cannot create ldap "
				      "privileged ldapi directory", true);
		return;
	}
	ldapi_path = talloc_asprintf(ldap_service, "%s/ldapi", priv_dir);
	talloc_free(priv_dir);
	if (ldapi_path == NULL) {
		goto failed;
	}

	status = stream_setup_socket(task->event_ctx, task->lp_ctx,
				     model_ops, &ldap_stream_priv_ops,
				     "unix", ldapi_path, NULL,
				     lp_socket_options(task->lp_ctx),
				     ldap_service);
	talloc_free(ldapi_path);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("ldapsrv failed to bind to %s - %s\n",
			 ldapi_path, nt_errstr(status)));
	}

#endif
	return;

failed:
	task_server_terminate(task, "Failed to startup ldap server task", true);
}
Example #11
0
static int init_sockets_smbd(const char *smb_ports, int listenset[FD_SETSIZE])
{
	int num_interfaces = iface_count();
	char * ports;
	int num_sockets = 0;
	int i, s;

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/

		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("init_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if (s < 0 || s >= FD_SETSIZE)
					return 0;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE");
				set_socket_options(s,user_socket_options);

				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False);

				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return 0;
				}

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
					return 0;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;

		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s < 0 || s >= FD_SETSIZE)
				return 0;

			/* ready to listen */
			set_socket_options(s,"SO_KEEPALIVE");
			set_socket_options(s,user_socket_options);

			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False);

			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("init_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return 0;
			}

			listenset[num_sockets] = s;
			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("init_sockets_smbd: Too many sockets to bind to\n"));
				return 0;
			}
		}
	}

	SAFE_FREE(ports);
	return num_sockets;
}
Example #12
0
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
{
	int num_interfaces = iface_count();
	int num_sockets = 0;
	int fd_listenset[FD_SETSIZE];
	fd_set listen_set;
	int s;
	int maxfd = 0;
	int i;
	char *ports;

	if (!is_daemon) {
		return open_sockets_inetd();
	}

		
#ifdef HAVE_ATEXIT
	{
		static int atexit_set;
		if(atexit_set == 0) {
			atexit_set=1;
			atexit(killkids);
		}
	}
#endif

#ifndef _XBOX
	/* Stop zombies */
	CatchChild();
#endif

	FD_ZERO(&listen_set);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		
		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if(s == -1)
					return False;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE"); 
				set_socket_options(s,user_socket_options);
     
				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False); 
 
				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return False;
				}
				FD_SET(s,&listen_set);
				maxfd = MAX( maxfd, s);

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
					return False;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;
		
		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s == -1)
				return(False);
		
			/* ready to listen */
#ifndef _XBOX
			set_socket_options(s,"SO_KEEPALIVE"); 
#endif
			set_socket_options(s,user_socket_options);
			
			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False); 
 
			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("open_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return False;
			}

			fd_listenset[num_sockets] = s;
			FD_SET(s,&listen_set);
			maxfd = MAX( maxfd, s);

			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
				return False;
			}
		}
	} 

	SAFE_FREE(ports);

        /* Listen to messages */

        message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
        message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
        message_register(MSG_SHUTDOWN, msg_exit_server);
        message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
	message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); 

#ifdef DEVELOPER
	message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); 
#endif

	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	DEBUG(2,("waiting for a connection\n"));
	while (1) {
		fd_set lfds;
		int num;
		
		/* Free up temporary memory from the main smbd. */
		lp_TALLOC_FREE();

		/* Ensure we respond to PING and DEBUG messages from the main smbd. */
		message_dispatch();

		memcpy((char *)&lfds, (char *)&listen_set, 
		       sizeof(listen_set));
		
		num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
		
		if (num == -1 && errno == EINTR) {
			if (got_sig_term) {
				exit_server_cleanly(NULL);
			}

			/* check for sighup processing */
			if (reload_after_sighup) {
				change_to_root_user();
				DEBUG(1,("Reloading services after SIGHUP\n"));
				reload_services(False);
				reload_after_sighup = 0;
			}

			continue;
		}
		
		/* check if we need to reload services */
		check_reload(time(NULL));

		/* Find the sockets that are read-ready -
		   accept on these. */
		for( ; num > 0; num--) {
			struct sockaddr addr;
			socklen_t in_addrlen = sizeof(addr);

			s = -1;
			for(i = 0; i < num_sockets; i++) {
				if(FD_ISSET(fd_listenset[i],&lfds)) {
					s = fd_listenset[i];
					/* Clear this so we don't look
					   at it again. */
					FD_CLR(fd_listenset[i],&lfds);
					break;
				}
			}

			smbd_set_server_fd(accept(s,&addr,&in_addrlen));
			
			if (smbd_server_fd() == -1 && errno == EINTR)
				continue;
			
			if (smbd_server_fd() == -1) {
				DEBUG(0,("open_sockets_smbd: accept: %s\n",
					 strerror(errno)));
				continue;
			}

			/* Ensure child is set to blocking mode */
			set_blocking(smbd_server_fd(),True);

			if (smbd_server_fd() != -1 && interactive) {
#ifdef _XBOX
				xb_IncClientCount();
#endif
				return True;
			}
			
			if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {


				/* Child code ... */			

				/* close the listening socket(s) */
				for(i = 0; i < num_sockets; i++)
					close(fd_listenset[i]);
				
				/* close our standard file
				   descriptors */
				close_low_fds(False);
				am_parent = 0;
				
				set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
				set_socket_options(smbd_server_fd(),user_socket_options);
				
				/* this is needed so that we get decent entries
				   in smbstatus for port 445 connects */
				set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
				
				/* Reset the state of the random
				 * number generation system, so
				 * children do not get the same random
				 * numbers as each other */

				set_need_random_reseed();
				/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
				if (tdb_reopen_all(1) == -1) {
					DEBUG(0,("tdb_reopen_all failed.\n"));
					smb_panic("tdb_reopen_all failed.");
				}

				return True; 
			}
			/* The parent doesn't need this socket */
			close(smbd_server_fd()); 

			/* Sun May 6 18:56:14 2001 [email protected]:
				Clear the closed fd info out of server_fd --
				and more importantly, out of client_fd in
				util_sock.c, to avoid a possible
				getpeername failure if we reopen the logs
				and use %I in the filename.
			*/

			smbd_set_server_fd(-1);

			/* Force parent to check log size after
			 * spawning child.  Fix from
			 * [email protected].  The
			 * parent smbd will log to logserver.smb.  It
			 * writes only two messages for each child
			 * started/finished. But each child writes,
			 * say, 50 messages also in logserver.smb,
			 * begining with the debug_count of the
			 * parent, before the child opens its own log
			 * file logserver.client. In a worst case
			 * scenario the size of logserver.smb would be
			 * checked after about 50*50=2500 messages
			 * (ca. 100kb).
			 * */
			force_check_log_size();
 
		} /* end for num */
	} /* end while 1 */

/* NOTREACHED	return True; */
}