Example #1
0
/*
  setup our listening sockets on the configured network interfaces
*/
static NTSTATUS cldapd_startup_interfaces(struct cldapd_server *cldapd, struct loadparm_context *lp_ctx,
					  struct interface *ifaces)
{
	int i, num_interfaces;
	TALLOC_CTX *tmp_ctx = talloc_new(cldapd);
	NTSTATUS status;

	num_interfaces = iface_count(ifaces);

	/* if we are allowing incoming packets from any address, then
	   we need to bind to the wildcard address */
	if (!lpcfg_bind_interfaces_only(lp_ctx)) {
		status = cldapd_add_socket(cldapd, lp_ctx, "0.0.0.0");
		NT_STATUS_NOT_OK_RETURN(status);
	}

	/* now we have to also listen on the specific interfaces,
	   so that replies always come from the right IP */
	for (i=0; i<num_interfaces; i++) {
		const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
		status = cldapd_add_socket(cldapd, lp_ctx, address);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	talloc_free(tmp_ctx);

	return NT_STATUS_OK;
}
Example #2
0
/*
  setup our listening sockets on the configured network interfaces
*/
NTSTATUS nbtd_startup_interfaces(struct nbtd_server *nbtsrv, struct loadparm_context *lp_ctx,
				 struct interface *ifaces)
{
	int num_interfaces = iface_count(ifaces);
	int i;
	TALLOC_CTX *tmp_ctx = talloc_new(nbtsrv);
	NTSTATUS status;

	/* if we are allowing incoming packets from any address, then
	   we also need to bind to the wildcard address */
	if (!lp_bind_interfaces_only(lp_ctx)) {
		const char *primary_address;

		/* the primary address is the address we will return
		   for non-WINS queries not made on a specific
		   interface */
		if (num_interfaces > 0) {
			primary_address = iface_n_ip(ifaces, 0);
		} else {
			primary_address = inet_ntoa(interpret_addr2(
							lp_netbios_name(lp_ctx)));
		}
		primary_address = talloc_strdup(tmp_ctx, primary_address);
		NT_STATUS_HAVE_NO_MEMORY(primary_address);

		status = nbtd_add_socket(nbtsrv, 
					 lp_ctx,
					 "0.0.0.0",
					 primary_address,
					 talloc_strdup(tmp_ctx, "255.255.255.255"),
					 talloc_strdup(tmp_ctx, "0.0.0.0"));
		NT_STATUS_NOT_OK_RETURN(status);
	}

	for (i=0; i<num_interfaces; i++) {
		const char *bcast = iface_n_bcast(ifaces, i);
		const char *address, *netmask;

		/* we can't assume every interface is broadcast capable */
		if (bcast == NULL) continue;

		address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
		bcast   = talloc_strdup(tmp_ctx, bcast);
		netmask = talloc_strdup(tmp_ctx, iface_n_netmask(ifaces, i));

		status = nbtd_add_socket(nbtsrv, lp_ctx, 
					 address, address, bcast, netmask);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	if (lp_wins_server_list(lp_ctx)) {
		status = nbtd_add_wins_socket(nbtsrv);
		NT_STATUS_NOT_OK_RETURN(status);
	}

	talloc_free(tmp_ctx);

	return NT_STATUS_OK;
}
Example #3
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 #4
0
/****************************************************************************
 True if we have two or more interfaces.
  **************************************************************************/
BOOL we_are_multihomed(void)
{
	static int multi = -1;

	if(multi == -1)
		multi = (iface_count() > 1 ? True : False);
	
	return multi;
}
Example #5
0
/*
  startup the nbtd task
*/
static void nbtd_task_init(struct task_server *task)
{
	struct nbtd_server *nbtsrv;
	NTSTATUS status;
	struct interface *ifaces;

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

	if (iface_count(ifaces) == 0) {
		task_server_terminate(task, "nbtd: no network interfaces configured", false);
		return;
	}

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

	nbtsrv = talloc(task, struct nbtd_server);
	if (nbtsrv == NULL) {
		task_server_terminate(task, "nbtd: out of memory", true);
		return;
	}

	nbtsrv->task            = task;
	nbtsrv->interfaces      = NULL;
	nbtsrv->bcast_interface = NULL;
	nbtsrv->wins_interface  = NULL;

	/* start listening on the configured network interfaces */
	status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "nbtd failed to setup interfaces", true);
		return;
	}

	nbtsrv->sam_ctx = samdb_connect(nbtsrv, task->event_ctx, task->lp_ctx, system_session(nbtsrv, task->lp_ctx));
	if (nbtsrv->sam_ctx == NULL) {
		task_server_terminate(task, "nbtd failed to open samdb", true);
		return;
	}

	/* start the WINS server, if appropriate */
	status = nbtd_winsserver_init(nbtsrv);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "nbtd failed to start WINS server", true);
		return;
	}

	nbtd_register_irpc(nbtsrv);

	/* start the process of registering our names on all interfaces */
	nbtd_register_names(nbtsrv);

	irpc_add_name(task->msg_ctx, "nbt_server");
}
Example #6
0
/*
  startup the cldapd task
*/
static void cldapd_task_init(struct task_server *task)
{
	struct cldapd_server *cldapd;
	NTSTATUS status;
	struct interface *ifaces;
	
	load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);

	if (iface_count(ifaces) == 0) {
		task_server_terminate(task, "cldapd: no network interfaces configured", false);
		return;
	}

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

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

	cldapd = talloc(task, struct cldapd_server);
	if (cldapd == NULL) {
		task_server_terminate(task, "cldapd: out of memory", true);
		return;
	}

	cldapd->task = task;
	cldapd->samctx = samdb_connect(cldapd, task->event_ctx, task->lp_ctx, system_session(task->lp_ctx), 0);
	if (cldapd->samctx == NULL) {
		task_server_terminate(task, "cldapd failed to open samdb", true);
		return;
	}

	/* start listening on the configured network interfaces */
	status = cldapd_startup_interfaces(cldapd, task->lp_ctx, ifaces);
	if (!NT_STATUS_IS_OK(status)) {
		task_server_terminate(task, "cldapd failed to setup interfaces", true);
		return;
	}

	irpc_add_name(task->msg_ctx, "cldap_server");
}
Example #7
0
/****************************************************************************
send out one query
****************************************************************************/
static BOOL query_one(char *lookup, unsigned int lookup_type)
{
	int j, count, flags;
	struct in_addr *ip_list=NULL;

	if (got_bcast) {
		printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
		ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
				     use_bcast?True:recursion_desired,
				     bcast_addr,&count, &flags);
	} else {
		struct in_addr *bcast;
		for (j=iface_count() - 1;
		     !ip_list && j >= 0;
		     j--) {
			bcast = iface_n_bcast(j);
			printf("querying %s on %s\n", 
			       lookup, inet_ntoa(*bcast));
			ip_list = name_query(ServerFD,lookup,lookup_type,
					     use_bcast,
					     use_bcast?True:recursion_desired,
					     *bcast,&count, &flags);
		}
	}

	if (give_flags)
		printf("Flags: %s\n", query_flags(flags));

	if (!ip_list) return False;

	for (j=0;j<count;j++) {
		if (translate_addresses) {
			struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
			if (host) {
				printf("%s, ", host -> h_name);
			}
		}
		printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
	}

	/* We can only do find_status if the ip address returned
	   was valid - ie. name_query returned true.
	*/
	if (find_status) {
		do_node_status(ServerFD, lookup, lookup_type, ip_list[0]);
	}

	safe_free(ip_list);

	return (ip_list != NULL);
}
Example #8
0
static struct sockaddr_storage *lookup_byname_backend(TALLOC_CTX *mem_ctx,
						      const char *name,
						      int *count)
{
	struct ip_service *ret = NULL;
	struct sockaddr_storage *return_ss = NULL;
	int j, i;
	NTSTATUS status;

	*count = 0;

	/* always try with wins first */
	if (NT_STATUS_IS_OK(resolve_wins(name,0x20,&ret,count))) {
		if ( *count == 0 )
			return NULL;
		return_ss = TALLOC_ARRAY(mem_ctx, struct sockaddr_storage,
					 *count);
		if (return_ss == NULL ) {
			free( ret );
			return NULL;
		}

		/* copy the IP addresses */
		for ( i=0; i<(*count); i++ )
			return_ss[i] = ret[i].ss;

		free( ret );
		return return_ss;
	}

	/* uggh, we have to broadcast to each interface in turn */
	for (j=iface_count() - 1;
	     j >= 0;
	     j--) {
		const struct sockaddr_storage *bcast_ss = iface_n_bcast(j);
		if (!bcast_ss) {
			continue;
		}
		status = name_query(name, 0x20, True, True,bcast_ss,
				    mem_ctx, &return_ss, count, NULL);
		if (NT_STATUS_IS_OK(status)) {
			break;
		}
	}

	return return_ss;
}
Example #9
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 #10
0
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
	int fd;
	struct ip_service *ret = NULL;
	struct in_addr *return_ip;
	int j, i, flags = 0;

	*count = 0;

	/* always try with wins first */
	if (resolve_wins(name,0x20,&ret,count)) {
		if ( count == 0 )
			return NULL;
		if ( (return_ip = (struct in_addr *)malloc((*count)*sizeof(struct in_addr))) == NULL ) {
			free( ret );
			return NULL;
		}

		/* copy the IP addresses */
		for ( i=0; i<(*count); i++ ) 
			return_ip[i] = ret[i].ip;
		
		free( ret );
		return return_ip;
	}

	fd = wins_lookup_open_socket_in();
	if (fd == -1) {
		return NULL;
	}

	/* uggh, we have to broadcast to each interface in turn */
	for (j=iface_count() - 1;
	     j >= 0;
	     j--) {
		struct in_addr *bcast = iface_n_bcast(j);
		return_ip = name_query(fd,name,0x20,True,True,*bcast,count, &flags, NULL);
		if (return_ip) break;
	}

	close(fd);
	return return_ip;
}
Example #11
0
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
	int fd;
	struct in_addr *ret = NULL;
	struct in_addr  p;
	int j, flags;

	*count = 0;

	fd = wins_lookup_open_socket_in();
	if (fd == -1)
		return NULL;

	p = wins_srv_ip();
	if( !is_zero_ip(p) ) {
		ret = name_query(fd,name,0x20,False,True, p, count, &flags);
		goto out;
	}

	if (lp_wins_support()) {
		/* we are our own WINS server */
		ret = name_query(fd,name,0x20,False,True, *interpret_addr2("127.0.0.1"), count, &flags);
		goto out;
	}

	/* uggh, we have to broadcast to each interface in turn */
	for (j=iface_count() - 1;
	     j >= 0;
	     j--) {
		struct in_addr *bcast = iface_n_bcast(j);
		ret = name_query(fd,name,0x20,True,True,*bcast,count, &flags);
		if (ret) break;
	}

 out:

	close(fd);
	return ret;
}
Example #12
0
static bool process_one(struct loadparm_context *lp_ctx, struct tevent_context *ev,
			struct interface *ifaces, const char *name, int nbt_port)
{
	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
	enum nbt_name_type node_type = NBT_NAME_CLIENT;
	char *node_name, *p;
	struct socket_address *all_zero_addr;
	struct nbt_name_socket *nbtsock;
	NTSTATUS status = NT_STATUS_OK;
	bool ret = true;

	if (!options.case_sensitive) {
		name = strupper_talloc(tmp_ctx, name);
	}
	
	if (options.find_master) {
		node_type = NBT_NAME_MASTER;
		if (*name == '-' || *name == '_') {
			name = "\01\02__MSBROWSE__\02";
			node_type = NBT_NAME_MS;
		}
	}

	p = strchr(name, '#');
	if (p) {
		node_name = talloc_strndup(tmp_ctx, name, PTR_DIFF(p,name));
		node_type = (enum nbt_name_type)strtol(p+1, NULL, 16);
	} else {
		node_name = talloc_strdup(tmp_ctx, name);
	}

	nbtsock = nbt_name_socket_init(tmp_ctx, ev, lp_iconv_convenience(lp_ctx));
	
	if (options.root_port) {
		all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, 
							    "0.0.0.0", NBT_NAME_SERVICE_PORT);
		
		if (!all_zero_addr) {
			talloc_free(tmp_ctx);
			return false;
		}

		status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to bind to local port 137 - %s\n", nt_errstr(status));
			talloc_free(tmp_ctx);
			return false;
		}
	}

	if (options.lookup_by_ip) {
		ret = do_node_status(nbtsock, name, nbt_port);
		talloc_free(tmp_ctx);
		return ret;
	}

	if (options.broadcast_address) {
		status = do_node_query(nbtsock, options.broadcast_address, nbt_port,
				       node_name, node_type, true);
	} else if (options.unicast_address) {
		status = do_node_query(nbtsock, options.unicast_address, 
				       nbt_port, node_name, node_type, false);
	} else {
		int i, num_interfaces;

		num_interfaces = iface_count(ifaces);
		for (i=0;i<num_interfaces;i++) {
			const char *bcast = iface_n_bcast(ifaces, i);
			if (bcast == NULL) continue;
			status = do_node_query(nbtsock, bcast, nbt_port, 
					       node_name, node_type, true);
			if (NT_STATUS_IS_OK(status)) break;
		}
	}

	if (!NT_STATUS_IS_OK(status)) {
		printf("Lookup failed - %s\n", nt_errstr(status));
		ret = false;
	}

	talloc_free(tmp_ctx);
	return ret;
}
Example #13
0
/************************************************************************** **
reload the list of network interfaces
 ************************************************************************** */
static void reload_interfaces(time_t t)
{
	static time_t lastt;
	int n;
	struct subnet_record *subrec;
	extern BOOL rescan_listen_set;
	extern struct in_addr loopback_ip;

	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return;
	lastt = t;

	if (!interfaces_changed()) return;

	/* the list of probed interfaces has changed, we may need to add/remove
	   some subnets */
	load_interfaces();

	/* find any interfaces that need adding */
	for (n=iface_count() - 1; n >= 0; n--) {
		struct interface *iface = get_interface(n);

		/*
		 * 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,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
			continue;
		}

		for (subrec=subnetlist; subrec; subrec=subrec->next) {
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}

		if (!subrec) {
			/* it wasn't found! add it */
			DEBUG(2,("Found new interface %s\n", 
				 inet_ntoa(iface->ip)));
			subrec = make_normal_subnet(iface);
			if (subrec) register_my_workgroup_one_subnet(subrec);
		}
	}

	/* find any interfaces that need deleting */
	for (subrec=subnetlist; subrec; subrec=subrec->next) {
		for (n=iface_count() - 1; n >= 0; n--) {
			struct interface *iface = get_interface(n);
			if (ip_equal(iface->ip, subrec->myip) &&
			    ip_equal(iface->nmask, subrec->mask_ip)) break;
		}
		if (n == -1) {
			/* oops, an interface has disapeared. This is
			 tricky, we don't dare actually free the
			 interface as it could be being used, so
			 instead we just wear the memory leak and
			 remove it from the list of interfaces without
			 freeing it */
			DEBUG(2,("Deleting dead interface %s\n", 
				 inet_ntoa(subrec->myip)));
			close_subnet(subrec);
		}
	}
	
	rescan_listen_set = True;
}
Example #14
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 #15
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 #16
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;
}
Example #17
0
static void reload_interfaces(time_t t)
{
	static time_t lastt;
	int n;
	bool print_waiting_msg = true;
	struct subnet_record *subrec;

	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
		return;
	}

	lastt = t;

	if (!interfaces_changed()) {
		return;
	}

  try_again:

	/* the list of probed interfaces has changed, we may need to add/remove
	   some subnets */
	load_interfaces();

	/* find any interfaces that need adding */
	for (n=iface_count() - 1; n >= 0; n--) {
		char str[INET6_ADDRSTRLEN];
		const struct interface *iface = get_interface(n);
		struct in_addr ip, nmask;

		if (!iface) {
			DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
			continue;
		}

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

		ip = ((const struct sockaddr_in *)(const void *)&iface->ip)->sin_addr;
		nmask = ((const struct sockaddr_in *)(const void *)
			 &iface->netmask)->sin_addr;

		/*
		 * 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((const struct sockaddr *)(const void *)&iface->ip)) {
			DEBUG(2,("reload_interfaces: Ignoring loopback "
				"interface %s\n",
				print_sockaddr(str, sizeof(str), &iface->ip) ));
			continue;
		}

		for (subrec=subnetlist; subrec; subrec=subrec->next) {
			if (ip_equal_v4(ip, subrec->myip) &&
			    ip_equal_v4(nmask, subrec->mask_ip)) {
				break;
			}
		}

		if (!subrec) {
			/* it wasn't found! add it */
			DEBUG(2,("Found new interface %s\n",
				 print_sockaddr(str,
					 sizeof(str), &iface->ip) ));
			subrec = make_normal_subnet(iface);
			if (subrec)
				register_my_workgroup_one_subnet(subrec);
		}
	}

	/* find any interfaces that need deleting */
	for (subrec=subnetlist; subrec; subrec=subrec->next) {
		for (n=iface_count() - 1; n >= 0; n--) {
			struct interface *iface = get_interface(n);
			struct in_addr ip, nmask;
			if (!iface) {
				continue;
			}
			/* Ensure we're only dealing with IPv4 here. */
			if (iface->ip.ss_family != AF_INET) {
				DEBUG(2,("reload_interfaces: "
					"ignoring non IPv4 interface.\n"));
				continue;
			}
			ip = ((struct sockaddr_in *)(void *)
			      &iface->ip)->sin_addr;
			nmask = ((struct sockaddr_in *)(void *)
				 &iface->netmask)->sin_addr;
			if (ip_equal_v4(ip, subrec->myip) &&
			    ip_equal_v4(nmask, subrec->mask_ip)) {
				break;
			}
		}
		if (n == -1) {
			/* oops, an interface has disapeared. This is
			 tricky, we don't dare actually free the
			 interface as it could be being used, so
			 instead we just wear the memory leak and
			 remove it from the list of interfaces without
			 freeing it */
			DEBUG(2,("Deleting dead interface %s\n",
				 inet_ntoa(subrec->myip)));
			close_subnet(subrec);
		}
	}

	rescan_listen_set = True;

	/* We need to wait if there are no subnets... */
	if (FIRST_SUBNET == NULL) {
		void (*saved_handler)(int);

		if (print_waiting_msg) {
			DEBUG(0,("reload_interfaces: "
				"No subnets to listen to. Waiting..\n"));
			print_waiting_msg = false;
		}

		/*
		 * Whilst we're waiting for an interface, allow SIGTERM to
		 * cause us to exit.
		 */
		saved_handler = CatchSignal(SIGTERM, SIG_DFL);

		/* We only count IPv4, non-loopback interfaces here. */
		while (iface_count_v4_nl() == 0) {
			sleep(5);
			load_interfaces();
		}

		CatchSignal(SIGTERM, saved_handler);

		/*
		 * We got an interface, go back to blocking term.
		 */

		goto try_again;
	}
}
Example #18
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;
}
Example #19
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,j;
	const char **ports;
	unsigned dns_port = 0;

#ifdef HAVE_ATEXIT
	atexit(killkids);
#endif

	/* Stop zombies */
	smbd_setup_sig_chld_handler(parent);

	ports = lp_smb_ports();

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (smb_ports) {
		char **l;
		l = str_list_make_v3(talloc_tos(), smb_ports, NULL);
		ports = discard_const_p(const char *, l);
	}

	for (j = 0; ports && ports[j]; j++) {
		unsigned port = atoi(ports[j]);

		if (port == 0 || port > 0xffff) {
			exit_server_cleanly("Invalid port in the config or on "
					    "the commandline specified!");
		}
	}

	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);
			if (ifss == NULL) {
				DEBUG(0,("open_sockets_smbd: "
					"interface %d has NULL IP address !\n",
					i));
				continue;
			}

			for (j = 0; ports && ports[j]; j++) {
				unsigned port = atoi(ports[j]);

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

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

		const char *sock_addr;
		char *sock_tok;
		const char *sock_ptr;

#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 (j = 0; ports && ports[j]; j++) {
				struct sockaddr_storage ss;
				unsigned port = atoi(ports[j]);

				/* 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 we fail to open any sockets
				 * in this loop the parent-sockets == NULL
				 * case below will prevent us from starting.
				 */

				(void)smbd_open_one_socket(parent,
						  ev_ctx,
						  &ss,
						  port);
			}
		}
	}

	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(messaging_server_id(msg_ctx),
			       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_SHUTDOWN, msg_exit_server);
	messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED,
			   smbd_parent_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, NULL, MSG_SMB_BRL_VALIDATE,
			   brl_revalidate);
	messaging_register(msg_ctx, NULL, MSG_SMB_FORCE_TDIS,
			   smb_parent_send_to_children);
	messaging_register(msg_ctx, NULL, MSG_SMB_KILL_CLIENT_IP,
			   smb_parent_send_to_children);
	messaging_register(msg_ctx, NULL, MSG_SMB_TELL_NUM_CHILDREN,
			   smb_tell_num_children);

	messaging_register(msg_ctx, NULL,
			   ID_CACHE_DELETE, smbd_parent_id_cache_delete);
	messaging_register(msg_ctx, NULL,
			   ID_CACHE_KILL, smbd_parent_id_cache_kill);

	if (lp_clustering()) {
		struct ctdbd_connection *conn = messaging_ctdbd_connection();

		register_with_ctdbd(conn, CTDB_SRVID_RECONFIGURE,
				    smbd_parent_ctdb_reconfigured, msg_ctx);
		register_with_ctdbd(conn, CTDB_SRVID_SAMBA_NOTIFY,
				    smbd_parent_ctdb_reconfigured, msg_ctx);
	}

#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 #20
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 #21
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; */
}
Example #22
0
static bool query_one(const char *lookup, unsigned int lookup_type)
{
	int j, count, flags = 0;
	struct sockaddr_storage *ip_list=NULL;

	if (got_bcast) {
		char addr[INET6_ADDRSTRLEN];
		print_sockaddr(addr, sizeof(addr), &bcast_addr);
		d_printf("querying %s on %s\n", lookup, addr);
		ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
				     use_bcast?true:recursion_desired,
				     &bcast_addr, &count, &flags, NULL);
	} else {
		const struct in_addr *bcast;
		for (j=iface_count() - 1;
		     !ip_list && j >= 0;
		     j--) {
			char addr[INET6_ADDRSTRLEN];
			struct sockaddr_storage bcast_ss;

			bcast = iface_n_bcast_v4(j);
			if (!bcast) {
				continue;
			}
			in_addr_to_sockaddr_storage(&bcast_ss, *bcast);
			print_sockaddr(addr, sizeof(addr), &bcast_ss);
			d_printf("querying %s on %s\n",
			       lookup, addr);
			ip_list = name_query(ServerFD,lookup,lookup_type,
					     use_bcast,
					     use_bcast?True:recursion_desired,
					     &bcast_ss,&count, &flags, NULL);
		}
	}

	if (!ip_list) {
		return false;
	}

	if (give_flags) {
		d_printf("Flags: %s\n", query_flags(flags));
	}

	for (j=0;j<count;j++) {
		char addr[INET6_ADDRSTRLEN];
		if (translate_addresses) {
			char h_name[MAX_DNS_NAME_LENGTH];
			h_name[0] = '\0';
			if (sys_getnameinfo((const struct sockaddr *)&ip_list[j],
					sizeof(struct sockaddr_storage),
					h_name, sizeof(h_name),
					NULL, 0,
					NI_NAMEREQD)) {
				continue;
			}
			d_printf("%s, ", h_name);
		}
		print_sockaddr(addr, sizeof(addr), &ip_list[j]);
		d_printf("%s %s<%02x>\n", addr,lookup, lookup_type);
		/* We can only do find_status if the ip address returned
		   was valid - ie. name_query returned true.
		 */
		if (find_status) {
			do_node_status(ServerFD, lookup,
					lookup_type, &ip_list[j]);
		}
	}

	free(ip_list);

	return (ip_list != NULL);
}
Example #23
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;
}